» » Удалённое выполнение кода в InterSystems Cache (RCE)

 

Удалённое выполнение кода в InterSystems Cache (RCE)

Автор: admin от 26-10-2015, 13:35, посмотрело: 468

Удалённое выполнение кода в InterSystems Cache (RCE)

Введение


В том случае, если вы управляете более чем одним сервером Cache может возникнуть задача выполнения произвольного кода из одного сервера Cache на другом. Кроме того, может потребоваться выполнение произвольного кода на удалённом сервере Cache, например, для нужд сисадмина… Для решения этих задач была разработана утилита RCE.

Какие вообще есть варианты решения подобных задач, и что предлагает RCE (Remote Code Execution) – под катом.

Что уже есть?


» Локальные команды ОС


Начнём с простого – выполнения локальных команд операционной системы из Cache. Для этого используются функции $zf:


  • $ZF(-1) – вызывает программу или команду операционной системы. Вызов осуществляется в новом процессе, родительский же процесс ждёт окончания выполнения вызванного процесса. После выполнения $ZF(-1) возвращает статус выполнения процесса: 0 в случае успешного выполнения, 1 в случае ошибки и -1 в случае если не получилось создать процесс.

    Выглядит это так: set status = $ZF(-1,"mkdir ""test folder""")


  • $ZF(-2) – аналогична, с той разницей, что основной процесс не ждёт результатов выполнения созданного процесса. В результате возвращается 0, если создание процесса прошло успешно и -1 если создать процесс не удалось.


Также можно использовать методы класса %Net.Remote.Utility, которые предоставляют собой удобные обёртки над стандартными функциями, их преимуществом является получение вывода вызванных процессов в более удобной форме:


  • RunCommandViaCPIPE – выполняет команду через Command Pipe. Возвращает созданное устройство и строку с выводом процесса. Напрямую выполнение команд на сервере с помощью Command Pipe описано на Хабре в этой статье.


  • RunCommandViaZF – выполняет команду через $ZF(-1). Записывает вывод процесса в файл, а также возвращает его в виде строки.


Альтернативным вариантом является использование терминальной команды ! (или $, они идентичны), которая открывает оболочку операционной системы внутри терминала Cache. Есть два режима работы:


  • Однострочный – вместе с ! передаётся сама команда. Она сразу выполняется интерпретатором оболочки, а её вывод отправляется на текущее устройство Cache. Предыдущий пример выглядит так:

    SAMPLES>! mkdir ""test folder""


  • Многострочный – сначала выполняется !, что приводит к открытию оболочки, в которую пользователь уже вводит команды операционной системы. Выход осуществляется с помощью команд quit или exit (в зависимости от оболочки):

    SAMPLES>! 
    C:InterSystemsCachemgrsamples> mkdir "test folder"
    C:InterSystemsCachemgrsamples> quit
    SAMPLES>


» Удалённое выполнение COS кода


Возможно с помощью класса %Net.RemoteConnection, где доступна следующая функциональность:


  • Открытие и изменение хранимых объектов;

  • Выполнение методов класса и объекта;

  • Выполнение запросов.



В данном коде происходит:


  • Подключение к серверу Cache;

  • Открытие экземпляра класса Sample.Person с Id 1;

  • Получение значения свойства;

  • Изменение значения свойства;

  • Установка аргументов для метода;

  • Вызов метода экземпляра;

  • Выполнение запроса Sample.Person:ByName.


Для работы %Net.RemoteConnection на стороне сервера, отправляющего запросы необходима настройка C++ биндинга.

Отдельно следует упомянуть о технологии ECP, о которой писали на Хабре, и которая позволяет вызывать удаленные JOB процессы со стороны сервера приложений на сервере БД.

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

RCE


Таким образом, перед проектом были поставлены следующие цели:


  • Выполнение скриптов на удалённых серверах из Cache;

  • Отсутствие необходимости настройки удалённого сервера (далее – клиента);

  • Минимальная настройка локального сервера (далее – сервера);

  • Прозрачное для пользователя переключение между командами операционной системы и COS;

  • Поддержка Windows и Linux в качестве клиента.


Иерархия классов проекта выглядит следующим образом:

Удалённое выполнение кода в InterSystems Cache (RCE)

Иерархия Машина – ОС – Инстанс служит для хранения информации, необходимой для доступа к удалённым серверам.
Для хранения команд служит класс RCE.Script, который содержит последовательный список – объектов класса RCE.Command, которые могут быть как командами ОС так и COS кодом.

Пример команд:
Set Сommand1 = ##class(RCE.Command).%New("cd 1",0)
Set Сommand2 = ##class(RCE.Command).%New("zn ""%SYS""",1)

Первый аргумент – текст команды, второй – уровень выполнения: 0 – ОС, 1 – Cache.

Пример создания нового скрипта:
Set Script = ##class(RCE.Script).%New()
Do Script.Insert(##class(RCE.Command).%New("touch 123",0))
Do Script.Insert(##class(RCE.Command).%New("set ^test=1",1))
Do Script.Insert(##class(RCE.Command).%New("set ^test(1)=2",1))
Do Script.Insert(##class(RCE.Command).%New("touch 1234",0))
Do Script.%Save()

Здесь на уровне ОС будут выполнены 1я и 4я команда, а 2я и 3я будут выполнены в Cache, причём процесс переключения уровня выполнения абсолютно прозрачен для пользователя.

» Механизмы выполнения


Сейчас поддерживаются следующие пути исполнения:













Сервер
Клиент
Linux
Linux, Windows (требуется установка SSH сервера на клиенте)
Windows
Linux, Windows (требуется установка SSH сервера на клиенте или psexec на сервере)
В том случае, если есть поддержка ssh на клиенте, сервер генерирует ssh команду и выполняет её на клиенте с помощью стандартного класса %Net.SSH.Session.

В случае же, если и сервер и клиент – под управлением ОС Windows, происходит генерация bat-файла, который потом отправляется на клиент и выполняется с помощью утилиты psexec.

» Добавление сервера


Загрузите классы из репозитория в любую область. В случае, если у вас Windows сервер и вы хотите управлять другими Windows серверами, установите значение глобала ^settings(«exec») равное пути к утилите psexec. На этом настройка завершена!

» Добавление клиента


Состоит в сохранении всех необходимых для аутентификации данных.


» Выполнение скрипта


Продолжая предыдущие примеры, выполнение скрипта происходит очень просто – с помощью метода ExecuteScript класса RCE.Instance, которому передаются объект скрипта и область выполнения (по умолчанию – %SYS):
Set Status = Instance.ExecuteScript(Script,"USER")

Выводы


RCE предоставляет удобный механизм удалённого выполнения кода из InterSystems Cache. Так как скрипты хранимые, вам необходимо написать скрипт только один раз, потом он может выполнятся когда угодно и на любом числе клиентов.

Ссылки


GitHub репозиторий RCE
Архив классов проекта RCE

Источник: Хабрахабр

Категория: Программирование, Системное администрирование, Веб-разработка

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *