Сплайсинг в PL/SQL через синонимы - в мирных целях

В компьютерных вирусах широко применяется технология сплайсинга. Смысл которой заключается в подмене кода вызываемой функции, выполнив свои действия, вирус должен уметь выполнить оригинальный код функции.
Сплайсинг может быть использован в PL/SQL. Для этого лучше всего использовать локальные синонимы.

Внимание: автор и редакция ответственности за ваши действия НЕ несут. См. УК РФ - статья 273. Создание, использование и распространение вредоносных программ для ЭВМ. Материал предоставлен исключительно в ознакомительных целях, для защиты функционала, а также его расширения для существующих приложений.

Итак, предположим у нас есть приложение, которое не поддерживает RAC. В коде приложения формируется анонимный блок порождающий множество job-ов через пакет DBMS_JOB. Перед этим приложение формирует входные данные для заданий в виде набора заполненных таблиц. При переходе в кластер происходит страшное: задания распределяются по узлам кластера, и происходит большая конкуренция с разных узлов за одни и теже сегменты.
Средствами пакета DBMS_JOB мы не можем заставить задания выполняться на том же узле, на котором они были порождены: этот пакет не "понимает" сервисов, и вообще говоря начиная с 10g НЕ рекомендуется к использованию.

Ну хорошо: мы можем в параметре instance процедуры dbms_job.submit выставить номер текущего узла:
dbms_job.submit(instance => dbms_utility.current_instance,...  ...  ...
Но если код приложения недоступен ?
В этом случае на помощь приходит сплайсинг: мы можем создать свой пакет (например под названием dbms_job_rac) который полностью повторяет спецификацию пакета dbms_job, а тело пакета мы определим по своему - в данном случае вызывая методы из DBMS_JOB и выставляя параметр instance в номер текущего узла.
Затем остается только создать локальный синоним в схеме приложения:
create synonym dbms_job for dbms_job_rac; 

На этом все - теперь приложение не подозревая об этом, будет вызывать наш пакет!

Этот способ работает, даже если код PL/SQL приложения зашифрован или приложение проверяет его контрольную сумму - ведь PL/SQL код НЕ меняется. Перехват управления производится без модификации исходного кода!

Как-то можно противостоять этому красивому перехвату ?
Да - очень просто: указывать вызов системного пакета напрямую, а не через синоним:
SYS.dbms_job.submit( ...
Любой инструмент может быть как орудием созидания, так и орудием разрушения ... :-)

1 комментарий:

  1. Всё бы неплохо было, если бы все "sys." указывали именно на пользователя SYS.
    Но если какой-то юзверь имеет возможность создавать в своей (!!!) схеме пакеты и создавать public synonym, то ему ничего не помешает сделать пакет с именем sys. Дать на него грант для всех и сделать публичный синоним. База Oracle "встаёт" колом ! (Вчера проверили на 10 XE. Сегодня на 10.2.0.2).
    Самое смешное что уже "починить" обратно тот же пользователь уже не может, так как drop-нуть public synonym ему мешает триггер XDB.XDB_PI_TRIG !!! Так что приходится ждать админа :-)

    ОтветитьУдалить