SQL — Conceptos y Laboratorio Pentest

Stack Query

Múltiples sentencias SQL en una sola consulta:

SELECT * FROM users; DROP TABLE users; --

Cláusulas Principales

Cláusula Uso
SELECT Obtener datos
FROM Indicar tabla fuente
WHERE Filtrar
GROUP BY Agrupar registros
HAVING Filtrar grupos
ORDER BY Ordenar
LIMIT Limitar filas
OFFSET Desplazar
UNION Combinar consultas
JOIN Relacionar tablas

Gestión de Usuarios y Permisos

CREATE USER '<username>'@'localhost' IDENTIFIED BY '<password>';
GRANT SELECT, INSERT ON <db_name>.* TO '<username>'@'localhost';
REVOKE UPDATE ON <db_name>.* FROM '<username>'@'localhost';
SHOW GRANTS FOR '<username>'@'localhost';

-- Información de permisos
SELECT * FROM INFORMATION_SCHEMA.USER_PRIVILEGES;
SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES;
SELECT @@secure_file_priv;

-- Tablas internas
mysql.user          -- usuarios y hashes
mysql.db            -- permisos por DB
mysql.tables_priv   -- permisos por tabla

Consultas Prácticas

Enumerar columnas de una tabla

SELECT GROUP_CONCAT('[',column_name,']' SEPARATOR '||')
FROM information_schema.columns
WHERE table_schema = '<db_name>' AND table_name = '<table_name>';

Extraer datos con CONCAT

SELECT GROUP_CONCAT(CONCAT('[',<col1>,']','::','[',<col2>,']') SEPARATOR ' | ')
FROM <db_name>.<table_name>;

Extraer con operador || (SQLite / MySQL)

SELECT GROUP_CONCAT('['||<col1>||']'||'::'||'['||<col2>||']', ' | ')
FROM <db_name>.<table_name>;

UNION + exfiltración

SELECT GROUP_CONCAT('[',<col1>,']', '[',<col2>,']' SEPARATOR ' | ')
FROM <db_name>.<table_name>
UNION
SELECT GROUP_CONCAT('[',<col1>,']', '[',<col2>,']' SEPARATOR ' | ')
FROM <db_name>.<table_name2>;

Filtrar por condición

SELECT GROUP_CONCAT(
  IF(<condicion>,
     CONCAT('[',<col1>,']','::','[',<col2>,']'),
     NULL
  ) SEPARATOR ' | ')
FROM <db_name>.<table_name>;

Time-Based Blind

-- ¿Primer carácter de <columna> donde id=1 es 'a'?
SELECT IF(
  (SELECT SUBSTRING(<columna>,1,1) FROM <db_name>.<table_name> WHERE id = 1) = 'a',
  SLEEP(5), NULL);

Enumerar tablas y columnas

-- Todas las columnas de todas las tablas
SELECT CONCAT('[',table_name,']', '[',column_name,']')
FROM information_schema.columns
WHERE table_schema = '<db_name>';

-- Filtrar columnas con 'pass' en el nombre
SELECT CONCAT('[',table_name,']', '[',column_name,']')
FROM information_schema.columns
WHERE table_schema = '<db_name>' AND column_name LIKE '%pass%';

Usuarios del sistema MySQL

-- Todos los usuarios
SELECT CONCAT('[',User,']', '[',Host,']') FROM mysql.user;

-- Con FILE privilege
SELECT CONCAT('[',User,']', '[',Host,']', '[',File_priv,']') FROM mysql.user;

-- Solo usuarios con File_priv = 'Y' (peligrosos en pentest)
SELECT CONCAT('[',User,']', '[',Host,']') FROM mysql.user WHERE File_priv = 'Y';

Tipos de JOIN

JOIN Resultado
INNER JOIN Solo coincidencias
LEFT JOIN Todo izquierda + coincidencias
RIGHT JOIN Todo derecha + coincidencias
FULL JOIN Todo de ambas

Comentarios por Motor

Motor Comentarios
MySQL --, #, /* */
PostgreSQL --, /* */
SQLite --, /* */
SQL Server --, /* */