- What is a Union-Based Attack? Unlike basic SQLi (which bypasses logins or causes errors), a union-based attack uses the
UNION operator to combine the results of the original query with an injected query, retrieving data from multiple parts of the database at once.
- Core Rule: For a
UNION SELECT query to work, both the original query and the injected query must have the exact same number of columns.
The 4-Step Attack Process
Step 1: Finding the Number of Columns
- Purpose: Determine how many columns the original query uses so the injected query matches.
- Technique: Use the
ORDER BY clause, incrementing the column number until the database throws an error.
- Example payload:
' ORDER BY 1 -- up to ' ORDER BY n --
- Success check: If the page loads normally, that column count exists. If it errors out, the previous number is the correct column count.
Step 2: Identifying Displayed Columns
- Purpose: Find out which of the columns are actually rendered on the webpage (since only displayed columns will show the extracted data).
- Technique: Inject numerical values into a
UNION SELECT statement matching the total column count.
- Example payload:
' UNION SELECT 1, 2, 3, 4, 5 -- (using unique numbers like 111 is recommended to avoid ID conflicts).
- Success check: Observe which numbers appear visually on the webpage.
Step 3: Extracting Data
- Purpose: Retrieve sensitive information (e.g., usernames and passwords) from target tables.
- Technique: Replace the numbers in the displayed column positions with database queries targeting specific tables and columns.
- Example payload:
' UNION SELECT NULL, username, password, NULL, NULL FROM users --
- Success check: Sensitive records render directly on the vulnerable page elements.
Step 4: Retrieving Table and Column Names (Metadata)
- Purpose: Discover table and column structures when they are unknown.
- Technique: Query database metadata schemas.
- Standard SQL (MySQL/PostgreSQL): Query
information_schema.tables and information_schema.columns.
- SQLite (Alternative): Query
sqlite_master where type='table' or tbl_name='users' to inspect table schemas.