Bypassing the Listener

The listener is the first contact we make in order to connect to the Oracle database. Therefore, as DBAs, it is also the front-end component we can secure. There are a few ways to secure the listener, and I’ll name some later.
When hackers look for an entry point to our database, any process that listens on the network and is related to Oracle is a target. The listener, in this scenario, is the first candidate, as it is the main process that listens to network connections, but is the listener the only one?

When we try to protect our database, there are several actions we can take. Some of them are network related, such as firewalls and network separations, while others are Oracle configurations. First, we can separate networks and listeners. If we have a server with many networks and databases, we can create a dedicated listener for each network so listeners that listen on specific networks won’t be able to connect clients to certain databases. Another thing we can do is to limit the rate of connections to the listener (by setting the RATE_LIMIT and CONNECTION_RATE_listener parameters in the listener.ora), so no one can overload the database. There are timeouts we can configure and more. Last thing we can do, is to configure which IP addresses are allowed to connect to the database, by setting the TCP.EXCLUDED_NODES and TCP.INVITED_NODES in the sqlnet.ora file.

How is a Connection Created?

Oracle manages connection differently on Windows and UNIX/Linux, and let’s focus on UNIX/Linux for now. When connecting to the database through the listener, the listener listens on the network, negotiates a TCP connection with the client, and then it spawns (using fork) a server process and hands off the open TCP socket to it. For the client that initiated the connection, this process is transparent and it uses the same open socket it negotiated with the listener. However, if the listener does not spawn a new process, but uses an existing one instead, it cannot hand off the socket, so it sends a redirect request to the client, which in turn creates a new connection with the existing process. In order to do this, this database process has to listen on the network as well, or it will not be able to respond to the client request. The process listens on a dynamic port (larger than 1024), cannot use a port that another process listens on (so it cannot be the same as the listener) and we don’t have control over the port number.

What Else is Listening?

In the past (if I remember correctly, 8i was the last version that had that), we had something called pre-spawned server processes. When we configured that, the listener started several server processes in advanced to reduce the amount of work when a new connection is coming. Once we initiated a connection, the listener simply redirected the client software to one of the existing server processes. As I explained above, these pre-spawned server processes were listening to the network waiting for the clients.
Today, we don’t have these pre-spawned server processes anymore, but we do have dispatchers. Dispatchers are used for the “shared server” architecture to allow connection pooling and multiplexing on the database side. Because the dispatchers start with the database, a client that wishes to connect using the shared server architecture will have to be redirected by the listener to one of the already started dispatchers. So the dispatchers have to listen on the network as well.
The last thing in this scenario is that most of us don’t use the “shared server” architecture, but if you use DBCA on Oracle 11.2 and up to create your database, it will configure a dispatcher for XDB, as XDB needs the “shared server” architecture.

Bypassing the Listener

Now that we know that processes that handle clients are listening to the network, let’s try to connect directly to one of them instead of going through the listener and see what happens.
First, we need to know which port the dispatcher is listening on, I guess port scanners can find that quite easily, we can also use netstat for that. Using “netstat -aptn” we can see the following line:

tcp    0    0 :::59806      :::*       LISTEN      2203/ora_d000_ora12

The port in this case is 59806, and the process is ora_d000_ora12 which is the dispatcher.
I’ll simply go through the database and query v$dispatcher:

SQL> select name,network from v$dispatcher;

NAME NETWORK
---- -----------------------------------------------------------
D000 (ADDRESS=(PROTOCOL=tcp)(HOST=liron-laptop)(PORT=59806))

In the NETWORK column we see the port the dispatcher is listening on. You also need to be aware that this is part of the databsae and it is not aware of services, so we can only connect to the instance by SID. I’ll create an entry in the tnsnames.ora for this port and SID:

disp =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(PORT=59806)(HOST = 10.230.14.120))
    )
    (CONNECT_DATA =
      (sid = ORA12)
    )
  )

Then I’ll connect it:

C:\Users\liron>sqlplus system/password@disp

SQL*Plus: Release 12.1.0.1.0 Production on Fri Oct 16 09:42:14 2015

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

Last Successful login time: Fri Oct 16 2015 09:40:44 -07:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

SQL>

And I’m in. The listener was DOWN at the time I connected.

What Else Does it Bypass?

Because we didn’t use the listener, then the obvious things are bypassed, such as any firewall configuration on the listener ports, the listener’s connection rate configuration, etc. Besides that, we need to remember that the sqlnet.ora file is loaded once at the start of a process. So if we add the TCP.EXCLUDED_NODES configuration, usually we just need to restart the listener. If there are dispatchers, we also need to restart the database itself so they will also reload the sqlnet.ora configuration. Until we restart the database, connections through the listener from the forbidden address will get the ORA-12537: TNS:connection closed error, but connections directly to the dispatcher will just work.
Another thing to remember is that the dispatchers use dynamic ports, we can’t control which port they will listen on, the OS allocates that. So every time you restrat the database, the dispatchers will listen on different ports.

Is There Anything Else?

I’m not aware of any other process that listens to the network, but if some features use such processes, I guess they would behave the same. Another thing to check is RAC, where there are many processes communicating between the nodes, and they are also potential processes to listen on the network. Last thing is that my examples are from 12.1.0.1 with no multitanent architecture, I don’t think 12.1.0.2 is any different, but because we can only connect to the SID, I guess there is no way to connect to a certain PDB using this method, but I haven’t tries that.

Advertisements

9 thoughts on “Bypassing the Listener

  1. hi
    wow nice.
    the first thing i did after i read it is to try it , awesome

    just one comment.
    the dynamic ports range in LINUX is from 49152 to 65535 (in windows its 1025 to 60000)
    and you can change the ports range :
    echo “65530 65535” > /proc/sys/net/ipv4/ip_local_port_range

    Like

  2. Aren’t you cheating? Dispatchers work due to local listeners. Tha’s right: listeners. So: you do not bypass the listener, you replaced the external listener process by an internal one.
    Which may be bad for the reasons you outlined (firewall, allowed incoming port checking) nut good for other reasons (the listener process itself cannot be tampered with – it’s now part of the database configuration)
    In SQL*Net V1 the listener actually handed off to a new TCP port. V2 uses the threaded model.

    Like

    • Hi Frank,
      I’m not cheating, the fact that the dispatcher has an open port allows me (and hackers of course) to connect directly to it without contacting the listener at all and maybe without being noticed as this is a dynamic port and a different process so it won’t be recorded anything in the listener log/trace.
      I am not sure I understand what you mean by threaded model of SQL*Net V2, but if you mean that the listener hands the connection off when connecting instead of sending a redirect, that is not the case with dispatchers. This is how the listener works when it starts a dedicated server process (on UNIX and Linux, not Windows), but with dispatchers it cannot do that, it redirects the connection to them.

      Like

  3. […] It is important to install only the features you actually use. If you don’t develop in APEX, don’t install it. If you don’t use Java in your database, don’t add it. Some of these features allow external access to the database and therefore increasing the attack surface. Our goal is to minimize the attack surface. The more access options we have to the database, the more it’s likely for an attacker to find a way in. An example for such an increase in the attack surface is the fact that Oracle starts a dispatcher for the database by default, and this dispatcher can be accessed directly. You can read all about it in my post bypassing the listener. […]

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s