OSCP Reference

9.2.8 Determine which database data and operations your identity can access Database Enumeration and Privilege Boundaries

← Stage index · Cheatsheet | Strategy map | Study methods: Extract opportunities from services

Recognize: common ports include MSSQL 1433, MySQL/MariaDB 3306 and PostgreSQL 5432, but instances can use other ports. Goal: establish database identity, authentication context, databases/schemas/tables, granted rights, useful data, server-side file access and command execution only where explicit privileges permit it.

Database administrator and operating-system administrator are different identities. Server-side file/program features act in the database server's filesystem and service-account context, not Kali's.

9.2.8.1 Inspect MySQL identity, readable data and file-operation rights MySQL / MariaDB

mysql -h TARGET -P PORT -u USER -p
SELECT VERSION(), USER(), CURRENT_USER();
SHOW DATABASES;
SHOW GRANTS;
USE DATABASE;
SHOW TABLES;
DESCRIBE TABLE;
SELECT * FROM TABLE LIMIT 20;
SELECT @@secure_file_priv;

Interpret: USER() shows the presented client identity; CURRENT_USER() shows the account used for privilege checking. secure_file_priv restricts server-side import/export: a directory constrains it, an empty value is unrestricted by that variable, and NULL disables these operations. The FILE privilege is still required.

9.2.8.1.1 MySQL variant — validate server-side file read/write prerequisites
SELECT LOAD_FILE('/path/on/database/server');
SELECT 'probe' INTO OUTFILE '/allowed/server/path/probe.txt';

Use only an authorized harmless path. LOAD_FILE returning NULL is ambiguous among missing file, permissions, size, FILE privilege and secure_file_priv. INTO OUTFILE will not overwrite an existing file. A written file becomes execution only if another privileged component consumes it.

9.2.8.2 Inspect SQL Server identity, grants and available operations Microsoft SQL Server

impacket-mssqlclient 'USER@TARGET'
impacket-mssqlclient 'DOMAIN/USER@TARGET' -windows-auth

Let the tool prompt for the password. At the SQL prompt:

SELECT @@VERSION;
SELECT SYSTEM_USER;
SELECT IS_SRVROLEMEMBER('sysadmin');
SELECT name FROM sys.databases;
USE DATABASE;
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES;
SELECT TOP 20 * FROM SCHEMA.TABLE;

Interpret: IS_SRVROLEMEMBER('sysadmin') returns 1, 0 or NULL; NULL is not success. Impacket also exposes helpers such as enum_impersonate and xp_cmdshell depending on version and rights.

9.2.8.2.1 MSSQL variant — command-execution boundary
EXEC xp_cmdshell 'whoami';

xp_cmdshell is disabled by default on new installations. Enabling it generally requires high privilege and changes server configuration; do not enable it merely to enumerate. When available, a sysadmin's child process normally runs as the SQL Server service account; an authorized non-sysadmin may use a configured proxy. Verify returned identity before choosing the next action.

9.2.8.2.2 MSSQL linked-server and login-context mapping

Treat a linked server as another authentication and authorization boundary. The local SQL login, its mapped remote login, remote SQL role and RPC/data-access settings can all differ.

SELECT SYSTEM_USER AS current_login,
       ORIGINAL_LOGIN() AS original_login,
       SUSER_SNAME() AS effective_login,
       IS_SRVROLEMEMBER('sysadmin') AS is_sysadmin;

SELECT name, product, provider, data_source, is_linked
FROM sys.servers
WHERE is_linked = 1;

EXEC master.dbo.sp_helplinkedsrvlogin;

Interpret: sys.servers proves configuration, not remote access. sp_helplinkedsrvlogin shows local-to-remote mappings; a NULL local login can represent a mapping that applies to all local logins. Preserve the local and remote identities separately.

After selecting one named link, test the smallest remote query supported by its configuration:

EXEC ('SELECT SYSTEM_USER AS remote_login,
              ORIGINAL_LOGIN() AS remote_original_login,
              IS_SRVROLEMEMBER(''sysadmin'') AS remote_is_sysadmin')
AT [LINKED_SERVER];

If RPC execution is disabled but data access is allowed, use a read-only pass-through query instead:

SELECT *
FROM OPENQUERY([LINKED_SERVER],
  'SELECT SYSTEM_USER AS remote_login,
          ORIGINAL_LOGIN() AS remote_original_login');

Decide: a returned remote identity enables only the operations granted to that mapped login. RPC OUT is disabled, login-mapping failures and data-access failures rule out different mechanisms; they do not prove the server is unreachable. If enum_impersonate identifies a specific permitted login, test only that login and always return to the original context:

EXECUTE AS LOGIN = 'LOGIN';
SELECT SYSTEM_USER, ORIGINAL_LOGIN(), SUSER_SNAME(), IS_SRVROLEMEMBER('sysadmin');
REVERT;

Do not enable RPC, create mappings or change server configuration merely to enumerate. A remote SQL query is not OS execution; independently validate any file or command facility and the operating-system identity behind it.

Sources: Microsoft sys.servers, sp_helplinkedsrvlogin, EXECUTE AS, and OPENQUERY.

9.2.8.3 Inspect PostgreSQL identity, data and server-side operation rights PostgreSQL

psql -h TARGET -p PORT -U USER -d postgres
\conninfo
\l
\du
\dn
\dt *.*
SELECT version(), current_user, session_user;
SELECT rolname, rolsuper, rolcreaterole, rolcreatedb
FROM pg_roles;
9.2.8.3.1 PostgreSQL variant — server file/program privilege boundary
SELECT pg_has_role(current_user, 'pg_read_server_files', 'member');
SELECT pg_has_role(current_user, 'pg_write_server_files', 'member');
SELECT pg_has_role(current_user, 'pg_execute_server_program', 'member');

Server-side COPY ... FROM/TO 'file' uses the PostgreSQL server's filesystem and service identity. COPY ... PROGRAM executes on the server and requires superuser or the corresponding predefined role. Client-side \copy reads/writes the client filesystem and is not the same primitive.

Failure cues: connection refusal/timeout is network or listener context; login rejection is authentication/context; an empty database list may be visibility limits; object denial is authorization. Query only bounded rows first. Never assume that reading application credentials or obtaining database admin implies OS execution.

Next action: identify application accounts, hashes/credentials, paths and linked systems; record the precise grant enabling any file or execution primitive; validate recovered credentials in the later credential block and re-enumerate after any identity change.

9.2.8.4 Inspect Redis access, data and enabled operations Redis

nmap -Pn -sV --script redis-info -p PORT TARGET
redis-cli -h TARGET -p PORT PING
redis-cli -h TARGET -p PORT INFO
redis-cli -h TARGET -p PORT ACL WHOAMI
redis-cli -h TARGET -p PORT ACL LIST

Authenticated when a password is legitimately known:

redis-cli -h TARGET -p PORT --askpass

PONG proves an accessible Redis command surface, not write/file/execution permission. Check ACLs, mode, bind/protected-mode and persistence/module configuration before reasoning about an effect. Do not run CONFIG SET, write keys or load modules during enumeration.

9.2.8.5 Oracle TNS/SID triage

nmap -Pn -sV --script oracle-tns-version -p 1521 TARGET
nmap -Pn --script oracle-sid-brute -p 1521 TARGET

A discovered SID/service name is a namespace clue, not credentials. Continue with an installed Oracle client only when a legitimate identity is available; preserve listener/version/SID evidence and do not treat a conventional port as Oracle proof. Source supplement: reviewed getSH Nmap Oracle block.

9.2.8.6 MongoDB — inspect readable databases with mongosh

Use when the service is MongoDB, commonly TCP/27017. Current installations use mongosh; the old mongo binary may be absent.

9.2.8.6.1 Reachable service without known credentials

# Reachable service without known credentials
mongosh --host TARGET --port PORT

9.2.8.6.2 Known account; -p prompts rather than storing the password in the command

# Known account; -p prompts rather than storing the password in the command
mongosh --host TARGET --port PORT -u USER -p --authenticationDatabase admin

Inside mongosh, choose the real database/collection:

show dbs
use DATABASE
show collections
db.getCollection('COLLECTION').find().limit(5)
db.getCollection('users').findOne({username: 'USER'})

Read: returned documents prove that identity can read those collections. An empty database list can reflect authorization, not an empty server. Classify recovered secrets and use the matching service. Login/operator injection is an application query issue, distinct from direct DB access. Do not overwrite account records just because the repo contains an update example.

Sources: upstream 1.

9.2.8.7 SQLite — inspect a recovered application database

Use when a downloaded/local application file is SQLite. It is a file format, not a remote listener.

file app.db
sqlite3 -readonly app.db
.tables
.schema users
PRAGMA table_info(users);
SELECT * FROM users LIMIT 5;
.quit

Read: identify the schema and credential format before choosing a recovery mode. Keep the database's provenance and any required WAL/SHM companions; a locked/incomplete copy can give misleading results. Recovered passwords/hashes → the credential procedure, not an assumption of OS or domain access.

Sources: upstream 1.


Top of document · Reference home