This article will discuss some internals of the Oracle Network Encryption. Generally, there are two ways how you can protect the transmission of the data between application server and the Oracle DB.
One way is to deploy TLS, certificate based wrapper around communication channel. This method will not be discussed here.
Another way is to deploy Oracle Network Encryption and is the subject of this discussion. When I first tried to evaluate Oracle Network Encryption I did not know the details of protection mechanism - I knew it encrypted DB traffic, that was all.
Once the Network Encryption was setup with the server and client (application server), the next step was to run network sniffer and verify the encryption was taking place. Oracle documentation describes how you configure either thick client (Oracle dedicated DB client such as sqlplus) or thin client (jdbc client, which was our case here).
Essentially, one needs to configure sqlnet.ora on the server side and sqlnet.ora on the client side, if thick client is deployed. In case of a thin client, sqlnet.ora is no longer relevant, but the "Properties" object of JDBC driver. One needs to add the two lines into the "Properties" object (or equivalent) in case of jdbc/thin client:
prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_LEVEL,"REQUESTED");
prop.setProperty(OracleConnection.CONNECTION_PROPERTY_THIN_NET_ENCRYPTION_TYPES,"(AES256)");
In my scenario I had several Oracle DBs running behind the Oracle application load balancer, called SCAN DB in Oracle terminology (Oracle Single Client Access Name (SCAN). Basically, your DB flow will hit SCAN DB first, then it will decide to what particular DB instance will this flow be redirected, based on the least-load algorithm.
[DB client/application server]-------------------[scan DB]----------------DB1, DB2,...DBN
Once all this is setup, one needs to trigger the interesting traffic between application (DB client) and server. First check against the encryption is simply an SQL query to show specifics of the active connection in the NETWORK_SERVICE_BANNER. Note in the table below that we have identified the program is JDBC Thin client and that AES256 has been identified as encryption algorithm.
Important to note is also that AES256 will only occur if there is active DB traffic flowing -otherwise you will get something like the below output. ("Encryption service" will be there, but no encryption algorithm!)
The interesting part starts here, when your sql query returns that encryption is indeed in place and you go ahead to verify the results with tcpdump.
Every single document I have found on the internet assumes that tcpdump will simply corroborate your sql response and it will show encrypted packets - in other words, big data chunks filled with high entropy bytes ("gibberish", if you want). In my case, I came across a very strange scenario - sql query returned that encryption was in place, but tcpdump showed some DB chunks in pure simple text !
I had no idea how this can be , so I had to carefully analyse network traffic dumps and work closely with the vendor on the client side to figure out what was missing.
First thing I noticed is that the initial connection string to the SCAN DB is sent in clear text and that it seems this is by design - the initial DB request will hit SCAN DB which must decide to which destination DB it will send request to. This goes in clear and is part of the initial Request/Connect and Response/Accept negotiation.
This is not so bad - there is a username, hostname or host IP address, port and service name defined , which are all to an extent sensitive details, but it's not like the content of the database or password in clear text etc. So, I thought, ok, if it was designed, so be it.
There were some other unpleasant surprises waiting along the way. Upon inspection of a longer pcap, I captured the authentication session in clear text as below.
Note below that AUTH_SESSKEY is not in cleartext - it is hashed, so even if it was transmitted in cleartext (as was here the case), the attacker should still need to brute force the captured hash.
As if this was not bad enough, some plain text DB traffic was captured too.
At this stage we made sure:
a) sql query returned that encryption was in place
b) significant part of DB communication was encrypted, indeed (tcpdump did show "gibberish" blocks of data)
c) some DB communication ("pure" DB data exchange and authentication session) was still in plain text
First, I was not sure if the authentication to the database was supposed to be encrypted- my intuition told me it should be encrypted, after all, this is a legitimate DB flow. On the other hand, it is not, so to speak "pure" DB exchange such as SELECT, MODIFY/DELETE data from the DB, so maybe it was not supposed to be encrypted after all?
Then we ran couple of tests in the test environment and confirmed that authentication of the DB session is also encrypted. So, there was something missing in the production setup.
This was verified in wireshark of the lab traffic that did encrypt authentication part. (note entropy in the SNS (Secure Network Services) message block)
The conclusion at this stage was that encryption should cover all DB communication including the authentication session. Vendor did find out the missing piece of configuration, patched that and this finally brought us to state where DB communication was encrypted in full. The only feedback that I have is relatively vague : database connection framework (talking about the application side) that does the database schema changes like DML and DDL had to be configured in addition to "Properties" object.
Further inspection of network captures revealed that numerous block appear that the Wireshark dissection will mark as "unknown" because the data in the TNS packet will be encrypted. If you go and search the data block of those packets, you will them encrypted.
The difference is apparent if you compare the network traffic captures of unencrypted and encrypted sessions.
Let us look at some encrypted messages below- (User OCI Function, Return OPI Parameter). Those two messages are part of the authentication session –
request and response. Note the "Data" block is encrypted. First, we have an example of encrypted "User OCI Function".
There is also "Return OPI Parameter"
Then we look at the unencrypted session, the same types of messages. Note the data block is now in plaintext. (User OCI Functions)
The same goes for Return OPI Parameter
Encrypted are also messages such as "Set Protocol" (client version
identification), "Describe Information" (language, date format). There are
probably others,too –actually, I think all other messages except initial
Request/Connect and Response/Accept will be encrypted.
An interesting side note- there is a minimal set of metadata one can read even from the encrypted packets that only vaguely describe what those packets are doing.
This knowledge comes from a single byte in the TNS header indicating it's the data ID - for example, "Return OPI Parameter" can be identified as a single byte ID below:
Bear in mind that this is only metadata - this will not give you any insight into the content of the data itself, it will just indicate the nature of the packet. (i.e. part of the authentication session, flushing out of some data in DML,services registration etc.)
Lessons learned - Oracle Network Encryption must encrypt DB data exchange and authentication part of the DB session. The only thing that it does not encrypt is the initial connection string, which is in plain text. This is most likely to accommodate the SCAN DB inspection of the incoming connection request and selecting the least loaded DB server.
Comments
Post a Comment