Статьи Перевод: Анатомия Oracle Часть5: О нахождении свидетельств кражи данных

Discussion in 'Статьи' started by Дрэгги, 10 Nov 2007.

  1. Дрэгги

    Дрэгги Elder - Старейшина

    Joined:
    26 Aug 2005
    Messages:
    284
    Likes Received:
    400
    Reputations:
    182
    Анатомия Oracle Часть5:

    О нахождении свидетельств кражи данных при отсутствии проверок



    David Litchfield [[email protected]]
    10th Августа 2007



    Исследование по пониманию безопасности согласно публикации NGSSoftware (NISR)
    ©2007 Next Generation Security Software Ltd
    http://www.ngssoftware.com


    Введение.

    Анализ подвергнутого риску сервера базы данных имеет свои собственные уникальные трудности. В других областях судебных исследований компьютера часто вполне очевидно, что преступление было совершено: например, на жестком диске обнаружены порнографические изображения; был установлен руткит; система замусорена. Однако же в случае вторжения в базу данных может казаться на первый взгляд, что ничего неблагоприятного не произошло - презумпция доказательства кажется отсутствующей. В физическом мире, если что-то украдено, то его нету и посредством этого воровство и становится очевидным, но с компьютерами, и в особенности с серверами баз данных, когда данные захвачены, берется только копия, а оригинал остается. Таким образом, то, что воровство произошло не становится немедленно очевидным, и при отсутствии могущего быть проверенным следа для исследователя становится еще более трудно определить, произошло ли нарушение. Согласно Национальной Конференции государственных законодательных органов [1] 35 штатов в США ввели законы об извещениях о нарушении безопасности, такие как Калифорнийский закон об Извещении о Нарушениях Безопасности баз данных, Билль 1386 Сената. Многие из этих законов только лишь требуют извещений в случае, когда атакующий получил доступ к информации, позволяющей идентифицировать личность (личного характера), а некоторые требуют, чтобы организации только лишь сообщали в случае когда атакующий получил доступ к незашифрованной личной информации. Знание того, получил ли атакующий доступ или нет критично, когда идет речь о принятии решения – сообщать или нет. Этот документ покажет, каким образом ответственный по инциденту может определить, произошло ли такое нарушение сервера базы данных Oracle, в случае когда нет никакого следа могущего быть проверенным, но подозревается, что атаковавший заполучил неправомерный ИЗБИРАТЕЛЬНЫЙ доступ к данным.

    Если атакующий прорывается в базу данных и создает объекты, такие как функции или таблицы и даже впоследствии удаляет их пытаясь скрыть их деятельность, то тогда они могут быть легко замечены [2]. Однако, если атакующий прорывается и просто спокойно ВЫБИРАЕТ отдельные данные, например имена пользователя, пароли или детали кредитных карт, и затем ускользает, то тогда их становиться намного более трудно выявить. Как кто бы то ни было может сказать, имела ли место такого рода атака в системе, где не задействована проверка? Притянуть какие-либо доказательства при подверженности риску такого рода может быть трудно, но, как покажет этот документ, все же есть несколько мест, где могут быть найдены свидетельства ВЫБОРОЧНЫХ запросов. Они включают в себя таблицы, используемые Автоматическим Архивом Рабочей нагрузки (AWR), Основанный на расходах Оптимизатор (CBO) и фиксированные обзоры общей области пула динамической памяти. В случае атак в виде SQL-инъекций через веб-сервер доказательства конечно могут иметься в файлах логов веб-сервера – настоящий документ однако же уделяет первостепенное внимание доказательствам непосредственно в самом сервере базы данных.

    Памятка: Этот документ конкретизирует информацию только об Oracle 10g Релизе 2 и должен использоваться в качестве директивы при исследовании других версий Oracle, так как нельзя дать никаких гарантий или сделать утверждений в отношении других версий. Если вас интересуют иные документы серии Судебный анализ Oracle пожалуйста см. здесь
    http://www.databasesecurity.com/oracle-forensics.htm



    Основанный на расходах Оптимизатор


    Всякий раз, когда пользователь выполняет запрос SQL, серверу необходимо скомпилировать запрос в план выполнения. Лучший способ сделать это определен Основанным на расходах Оптимизатором (CBO), который пытается уменьшить количество системных ресурсов, необходимых для обрабатывания запроса. Статистические данные о CBO записываются в таблицы вспомогательным процессом Системного Монитора (SMON). Одна из таких таблиц, таблица COL_USAGE$, используется для того, чтобы записать информацию о предикатах, используемых в запросах ВЫБОРА или, другими словами, столбцах, используемых в пунктах запроса ГДЕ и типе предиката, таком как равняется, подобно, ряд (диапазон) и так далее. В Релизе 2 10g эта таблица обновляется процессом SMON каждые двадцать минут. Информация в этой таблице может использоваться судебным ревизором или ответственным за инцидент, чтобы вывести детали о запросах ВЫБОРА, которые были выполнены в базе данных, что может указать на то, могли бы или нет данные быть украдены. Перед тем, как показать, как именно, давайте рассмотрим определение таблицы.


    SQL> DESC COL_USAGE$
    Name Null? Type
    ----------------------------------------- -------- ---------------
    OBJ# NUMBER
    INTCOL# NUMBER
    EQUALITY_PREDS NUMBER
    EQUIJOIN_PREDS NUMBER
    NONEQUIJOIN_PREDS NUMBER
    RANGE_PREDS NUMBER
    LIKE_PREDS NUMBER
    NULL_PREDS NUMBER
    TIMESTAMP DATE


    Столбец OBJ# содержит ID объекта таблицы, к которой был обращен запрос, а столбец INTCOL# содержит номер столбца таким, каким он был взят из колонки COL# в таблице COL$, используемый с предикатом. Таким образом, например, если Z будет определен как 3-ий столбец в COL$ в таблице COLTEST и запрос 'SELECT * FROM COLTEST, WHERE(где) Z = 0' выполняется, тогда столбец INTCOL# в COL_USAGE$ будет 3. Столбец TIMESTAMP производит запись в секунду, ближайшую к моменту, когда запись была добавлена к таблице COL_USAGE$ - а не в то время, когда выполнялся записываемый запрос. Это важно отметить, выстраивая ход событий во времени. Поскольку процесс SMON записывает изменения в таблицу COL_USAGE$ каждые 20 минут, для данной записи максимальный временной перекос может быть в 20 минут. Еще один пункт, который следует отметить в отношении столбца TIMESTAMP – это то, что если в той же самой таблице, используя тот же самый предикат, выполняется новый запрос, TIMESTAMP обновляется; таким образом более старые записи будут перезаписаны. Остающиеся столбцы указывают тип предиката. Например, запись строки для EQUALITY_PREDS будет сгенерирована после запроса вида 'SELECT X FROM COLTEST WHERE Z = 5'. Строка RANGE_PREDS будет сгенерирована после запроса вида 'SELECT X FROM COLTEST WHERE Z > 0 AND Z <100'. Строка NULL_PREDS была бы сгенерирована после запроса 'SELECT Y FROM COLTEST, WHERE Y IS NULL', а строка LIKE_PREDS - после запроса вида 'SELECT Y FROM COLTEST WHERE Y LIKE ' %A %".

    Формируя дамп содержимого этой таблицы, может быть получена полная картина того, из каких таблиц производился выбор и какие столбцы с какими предикатами использовались. Поэтому чтобы привести результаты в более ясный вид, на каждый тип предиката может делаться запрос по-отдельности. Например, формирование дампа LIKE_PREDs может быть сделано следующим образом:

    SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';

    Session altered.

    SQL> SELECT C.TIMESTAMP, O.NAME, C.INTCOL#, C.LIKE_PREDS FROM
    COL_USAGE$ C, OBJ$ O WHERE C.OBJ#=O.OBJ# AND C.LIKE_PREDS > 0;

    TIMESTAMP NAME INTCOL# LIKE_PREDS
    ------------------- -------------- ------- ----------
    2007-08-08 06:10:27 COL$ 6 1
    2007-08-09 18:06:55 OBJ$ 4 2



    Если мы посмотрим на первую строку данных, мы сможем увидеть, что кто-то ВЫБРАЛ (SELECT) из таблицы COL$, используя 6-ой столбец с предикатом "like". Как это бывает, такая строка была создана в COL_USAGE$ после того как атакующий, во время поиска интересных таблиц, с которых можно было бы сделать дамп данных, выполнил следующий SQL:

    SQL> SELECT TABLE_NAME FROM DBA_TAB_COLS WHERE COLUMN_NAME LIKE
    '%CREDITCARD%';

    DBA_TAB_COLS – это тот вид, что переносится на таблицу COL$ - COLUMN_NAME в нем соответствует 6-ому столбцу в таблице COL$ - который "NAME" - другими словами название столбца. Одна вещь, которую надо здесь отметить - то, что OBJ# в COL_USAGE$ имеет отношение не к ID объекта вида, а к ID объекта низлежащей таблицы.


    Для этого метода ясно, что для того, чтобы он был полезным, необходимо иметь возможность заполучить базис, с которым можно было бы сравнивать текущие данные. Этот базис может быть установлен множеством способов. Если случается, что была создана резервная копия таблицы COL_USAGE$, тогда проводимые с ней сравнения могут им быть, если только конечно резервные копии были сделаны во временной период вне вторжения. Если же резервные копии COL_USAGE$ недоступны, тогда это может быть возможным посредством исследования приложений базы данных организации и разговоров с администраторами базы данных и разработчиками чтобы определить, какие таблицы должны появиться в таблице COL_USAGE$ и при каких условиях. Например, если приложения организации всегда только лишь обращали запрос к таблицам 1, 2 и 3, но не 4 и случается так, что 4 появляются среди данных COL_USAGE$, тогда может быть сделан вывод, что это уже не находится в пределах границ того, что является "нормальным", давая ход дальнейшим исследованиям. Есть и еще большие ограничения, когда речь идет о выявлении деталей атак с использованием данных COL_USAGE$. Очевидным является то, что если атаковавший не предицирует свой запрос со столбцом из рассматриваемой таблицы, то никакая запись и не будет создана в таблице COL_USAGE$. Таким образом, если атакующий делает запрос вида ‘SELECT PASSWORD FROM SYS.USER$ WHERE NAME = ‘SYS’‘, тогда строка будет создана однако строка не будет создана при следующем запросе, ‘SELECT PASSWORD FROM SYS.USER$‘.

    Если нападавший мог выполнить произвольный SQL с привилегиями администратора базы данных, например, воспользовавшись недостатком PL/SQL инъекции, то тогда атакующий мог УДАЛЯТЬ (DELETE) из этой таблицы. При этом действии, однако, свидетельство этого УДАЛЕНИЯ было бы оставлено в логах восстановления, точно так же как и непосредственно файлы данных [2].

    Установленные виды V$ в Общедоступном Пуле

    Есть множество виртуальных таблиц и видов, которые поддерживает Oracle в функциональных целях. Эти виды доступны для администраторов баз данных и часто могут содержать свидетельства атак. Два таких вида представляют особый интерес - V$SQL и V$DB_OBJECT_CACHE.

    Установленный вид V$SQL содержит список недавно выполненных SQL. Это круговой буфер, поэтому когда он заполняется новая информация заменяет старую. В зависимости от размера общедоступного пула, и в зависимости от длины каждого запроса буфер может содержать большое количество запросов. Установленный по умолчанию 10g Релиз 2 может поддерживать приблизительно до 7000 запросов прежде, чем более старые записи будут перезаписаны.

    SQL> SET LONG 3000000
    SQL> SELECT LAST_ACTIVE_TIME, PARSING_USER_ID, SQL_FULLTEXT FROM V$SQL;


    Доказательство деятельности нападавшего может быть найдено в этом установленном виде, и тщательное изучение SQL_TEXT должно это выявить. Следует подчеркнуть, что если атакующий сможет найти способ выполнить произвольный SQL в качестве администратора базы данных, которых много, тогда они могут вычистить SQL из этого вида выполнив ‘ALTER SYSTEM FLUSH SHARED_POOL’.

    V$DB_OBJECT_CACHE содержит детали об объектах в кэше библиотеки. Есть две вещи, представляющие интерес в отношении именно этого вида . Во-первых, если объект существует в кэше, то тогда вероятно к нему недавно был совершен доступ, и во-вторых этот вид может содержать отрывки недавно выполненного SQL.


    SQL> DESC V$DB_OBJECT_CACHE
    Name Null? Type
    ---------------------------------- -------- ----------------
    OWNER VARCHAR2(64)
    NAME VARCHAR2(1000)
    DB_LINK VARCHAR2(64)
    NAMESPACE VARCHAR2(28)
    TYPE VARCHAR2(28)
    SHARABLE_MEM NUMBER
    LOADS NUMBER
    EXECUTIONS NUMBER
    LOCKS NUMBER
    PINS NUMBER
    KEPT VARCHAR2(3)
    CHILD_LATCH NUMBER
    INVALIDATIONS NUMBER

    Тип данных строки, хранимых в столбце NAME зависит от столбца NAMESPACE. Если столбец NAMESPACE строки – это 'CURSOR', тогда NAME содержит данные SQL - если NAMESPACE – это 'TABLE/PROCEDURE', тогда NAME содержит таблицу или процесс, к которым недавно обращались. Таким образом, чтобы сформировать дамп списка недавно выполненных запросов можно выполнить

    SQL> SELECT NAME FROM V$DB_OBJECT_CACHE WHERE NAMESPACE = 'CURSOR';

    Чтобы обратиться к списку таблиц и процессов, к которым недавно был совершен доступ, можно выполнить


    SQL> SELECT OWNER, NAME FROM V$DB_OBJECT_CACHE WHERE NAMESPACE =







    'TABLE/PROCEDURE' ORDER BY 1;

    Исследуя эти данные ответственный по инциденту может определить, содержится ли там доказательство атаки. Этот установленный вид представляет определенные преимущества по сравнению с видом V$SQL. Как уже указано, атакующий может очистить вид V$SQL выполнением ‘ALTER SYSTEM FLUSH SHARED_POOL’. Это однако уже не относится к данным в виде V$DB_OBJECT_CACHE – он не очищается.

    Автоматический Архив Рабочей нагрузки

    Автоматический Архив Рабочей нагрузки (AWR) используется для того, чтобы собирать статистику, связанную с процессом работы. Записи, детализирующие информацию о запросах SQL и доступе к объектам хранятся AWR, и это может выявить, какие действия атаковавший, возможно, предпринял. AWR обеспечивает определенные преимущества по сравнению с видами V$, поскольку данные AWR постоянны, в то время как данные V$ теряются, когда база данных завершает работу и перезапускается, но один из недостатков использования данных AWR – это то, что AWR должен делать снимок, и он делает его каждую секунду в то самое время, когда имеет место атака. Если предположить что, конечно, некоторые из действий атаковавшего были зафиксированы AWR, тогда они могут быть найдены выполнив следующий запрос:


    SQL> SELECT ST.PARSING_SCHEMA_ID, TX.SQL_TEXT FROM WRH$_SQLSTAT ST,
    WRH$_SQLTEXT TX WHERE TX.SQL_ID = ST.SQL_ID;

    При нахождении “интересных” запросов может быть снята отметка о времени, ссылаясь на SQL_ID:

    SQL> SELECT TIMESTAMP FROM WRH$_SQL_PLAN WHERE SQL_ID = ‘b7v16a01s0f86’

    Следует отметить, что иногда некоторые строки в WRH$_SQLTEXT не имеют соответствующего SQL_ID в таблице WRH$_SQLSTAT. Например, на одной из проверяемых машин, используемых в лаборатории для этого документа, следующий запрос произведет 6 строк:

    SQL> SELECT SQL_TEXT FROM WRH$_SQLTEXT WHERE SQL_ID NOT IN (SELECT
    DISTINCT SQL_ID FROM WRH$_SQLSTAT);

    Вместо заключения:

    Этот документ показал, где могут быть найдены доказательства случаев воровства данных в Oracle 10g Релиз 2 – в особенности это таблицы, поддерживаемые с рабочими целями и охватывающие Основанный на Расходах Оптимизатор, установленные виды динамической работы V$ и Автоматический Архив Рабочей нагрузки. В отсутствии следов для проверок эти таблицы могут помочь определить, произошла ли атака. По мнению автора должно быть подчеркнуто, что отсутствие каких-либо свидетельств в этих таблицах не будет служить доказательством, что атака не имела места - может быть выяснено, что атакующий с соответствующим уровнем доступа может предпринять шаги, чтобы замести свои следы, несмотря даже на то, что делая это он может оставить доказательства в другом месте.


    [1] http://www.ncsl.org/programs/lis/cip/priv/breachlaws.htm
    [2] http://www.databasesecurity.com/dbsec/Locating-Dropped-Objects.pdf




    Перевод: Дрэгги
     
    16 people like this.