A type of SQL Injection where the attacker use the UNION SQL operator to combine the results of an original, legitimate query with the results of an injected malicious query.
Requirements
- that the application displays the original query in the HTTP response.
- that the original query has the same number of columns as the injected query.
- that the data types of the columns in both queries are compatible.
Process
Based on the requirements above the process is usually:
- Determine number of columns returned by the original query. Can be done by injecting
ORDER BY <int>and incrementing <int> until an error occurs, or injectingUNION SELECT NULL, NULL, ...increasing the amount ofNULLuntil a success occurs. - Identify which columns can hold string data (or whatever type the attacker wants to extract) to ensure the injected payload is displayed correctly
- If the column of the queries are not equal it is possible to add junk data to the table with least columns until the number of columns are equal. Using
NULLto fill the junk columns ensure that the data types are compatible. - Knowing the number of columns and their data types the data can now be extracted by injecting a query containing
UNION, e.g.,UNION SELECT username, password FROM users.
Examples
Adding junk columns for equal columns
The original query from a web shop is SELECT * from products where product_id = '<user input>' where products have 4 columns. We want to see username data in the passwords table which have only 1 column.
We therefore inject the payload 1' UNION SELECT username, 2, 3, 4 from passwords --<space>, so that the usernames are shown in the first column and junk are in the remaining:
SELECT * from products where product_id = '1' UNION SELECT username, 2, 3, 4 from passwords-- '
+-----------+-----------+-----------+-----------+
| product_1 | product_2 | product_3 | product_4 |
+-----------+-----------+-----------+-----------+
| admin | 2 | 3 | 4 |
+-----------+-----------+-----------+-----------+which reveals that there is a user with username admin.
Integers were used as junk in this example for unique junk values to show how junk is inserted in the resulting table. Usually NULL values are used to ensure data compatibility.