Связь по протоколу dde с приложением ms windows на примере excel мрв как dde сервер

Обновлено: 07.07.2024

Лабораторный инструмент имеет RS232 порт, через который выводятся данные каждые 10 минут. Я хотел бы использовать значения из выводимых данных в формах, формулах и моих скриптах VBA в документах Microsoft Excel.

Требования:

  • Advanced Serial Data Logger (ASDL) Professional или пробная версия;
  • Модуль "ASCII data parser and query" для логгера;
  • Модуль "DDE server" для Advanced Serial Data Logger.

Подразумевается что:

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

Вы можете работать в Microsoft Excel, в частности создавать и использовать формы.

Решение:

Замечание: Этот пример базируется на предыдущем примере с именем "Данные из последовательного порта и Excel. Рисование графиков в реальном времени". Этот пример будет использовать настройки парсера и пример данных их этого примера. Поэтому вы можете прочитать этот обучающий пример перед продолжением чтения этого примера.

Парсер готов и мы протестировали его в предыдущем примере. Если парсер верно настроен, то в окне DDE сервера будут отображены наши переменные и их значения (рис.1).

Данные из COM порта, Excel и DDE. Окно DDE сервера.

Рис.1. Данные из COM порта, Excel и DDE. Окно DDE сервера.

Все переменные теперь готовы для использования в Microsoft Excel. Имя переменной отображается в колонке "Имя". Вы должны знать имя DDE сервера и имя топика для того, чтобы получать данные через DDE. Эта информация представлена на следующем рисунке (рис.2 поз.1). Пожалуйста, обратите внимание, что имя сервера может отличаться на вашем компьютере.

Данные из COM порта, Excel и DDE. Параметры сервера DDE.

Рис.2. Данные из COM порта, Excel и DDE. Параметры сервера DDE.

Кликните на кнопке "OK" и закройте окно настройки модуля сервера DDE, а затем кликните кнопку "OK" в окне настройки конфигурации.

Поскольку мы хотим рисовать графики в реальном времени, то мы должны подготовить файл Excel перед следующим шагом. В этом примере мы создали диаграмму с тремя графиками. Каждый график базируется на данных их колонок A, B или C. Мы будет помещать значения переменных FLOW1, VOLW1 и TEMP1 в соответствующую колонку, а Excel будет автоматически обновлять нашу диаграмму. Мы будем использовать только последние 30 значений на нашей диаграмме. В этом примере мы поместили 3 ссылки на DDE переменные в ячейки D21-F21 вида: "=testcore|ddesrv!srviFLOW1" (без кавычек) (рис.3 и 4). Как вы можете видеть, имя сервера, имя топика и имя переменной указаны в этой ссылке на данные DDE.

Данные из COM порта, Excel и DDE. Ссылки на данные DDE.

Рис.3. Данные из COM порта, Excel и DDE. Ссылки на данные DDE.

После того, как вы создали ссылки на данные DDE в вашем документе, Microsoft Excel автоматически запустит логгер и получит данные. Если логгер уже запущен, то Microsoft Excel попробует считать данные из запущенной программы. Если логгер еще не получил и не обработал никаких данных, то Microsoft Excel отобразит информацию о неверной ссылке, но считает значения, как только данные будут получены и обработаны логгером.

Теперь мы готовы для создания кода VBA, который будет обрабатывать наши DDE данные. Этот код будет копировать значения DDE в колонки, передвигать старые значения и добавлять строки в историю значений (рис.4, 5).

Данные из COM порта, Excel и DDE. Исходный документ Excel.

Рис.4. Данные из COM порта, Excel и DDE. Исходный документ Excel.

Рисунок выше содержит следующие элементы:

  1. Данные DDE будут помещаться здесь, и будут служить источником данных для графиков;
  2. График;
  3. История данных.

Код VBA из файла Excel

Файл Excel, который мы создали, вы можете скачать здесь и использовать в вашей работе.

Хорошо. Процедура настройки завершена и пришло время попробовать получить данные в Excel.

Подсоедините ваше устройство или включите его, если это необходимо. Попробуйте принять пакет данных от устройства. Если парсер верно настроен, то в Excel будут отображены наши DDE переменные и их значения (рис.5).

Данные из COM порта, Excel и DDE. Результаты.

Рис.5 Данные из COM порта, Excel и DDE. Результаты.

Рисунок выше содержит следующее:

  1. Последние 30 значений DDE данных;
  2. Последние значения переменных DDE сервера;
  3. История данных DDE.

Файл Excel со всеми значениями и графиками вы можете скачать здесь.

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

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

2. Описание протокола DDE.

Начнем с кратного описания протокола DDE. Материал статьи охватывает только ту часть API протокола, которая необходима для организации "горячего" канала DDE.

По протоколу DDE, сервер в первую очередь должен зарегистрировать себя в библиотеке DDEML. После этого он регистрирует предоставляемые сервисы.

Клиентское приложение также сначала регистрирует себя в библиотеке DDEML. После этого клиентское приложение создает канал связи с сервером.

Протокол DDE поддерживает три вида обмена данными между клиентом и сервером:

  • По явному запросу
  • "Теплый канал"
  • "Горячий канал"

В первом случае клиент явным образом посылает серверу запрос, указывая нужный элемент данных. Сервер, получив подобный запрос, предоставляет клиенту эти данные.

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

В случае "горячего канала" сервер будет отправлять клиенту данные, не ожидая явного запроса при их изменении.

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

В библиотеке DDEML данные адресуются трехступенчатой схемой: сервис (service), раздел (topiс) и элемент данных (data item). Для сервера DDE приложения MS Excel, эта схема выглядит следующим образом:

Для установления связи, приложение должно сначала зарегистрировать себя в библиотеке DDEML и получить свой программный идентификатор. Этот идентификатор необходимо хранить в течение всей работы, так как для каждого приложения, которое регистрируется в библиотеке DDEML, создается своя копия необходимых структур данных.

Параметры, которые передаются функции при вызове:

  • pidInst - ссылка на переменную типа <двойное слово>, в которую функция запишет программный идентификатор, присваиваемый приложения библиотекой DDEML. Перед вызовом функции программа должна обнулить значение этой переменной.
  • pfnCallback - указатель на функцию обратного вызова.
  • afCmd - набор битовых флагов инициализации, а также устанавливающий некоторые специфические условия работы с библиотекой.
  • ulRes - зарезервировано и должно быть равно нулю.

В случае успешной регистрации, функция DdeInitialize возвращает нулевое значение. Если при инициализации произошла ошибка, то функция вернет код ошибки.

Если приложение больше не собирается работать с библиотекой DDEML, то оно должно вызвать функцию DdeUninitialize, передав ей в качестве параметра программный идентификатор, полученный при регистрации:

После успешной инициализации, клиентское приложения должно создать канал связи с сервером. Для каждого сервиса и раздела создается свой канал связи. После успешного создания канала, ему присваивается идентификатор, который указывается в дальнейших транзакциях, как клиентом, так и сервером.

Адресация происходит посредством строк, однако в транзакциях используются их идентификаторы. Эти идентификаторы присваиваются каждой строке библиотекой DDEML и хранятся в специальной системной таблице идентификации строк. Для создания идентификатора строки, необходимо воспользоваться функцией DdeCreateStringHandle:

Функция получает следующие параметры:

  • idInst - программный идентификатор приложения, полученный при регистрации в библиотеке DDEML;
  • psz - адрес текстовой строки, завершенной двоичным нулем. Длина строки не должна превышать 255 байт.
  • iCodePage - кодовая страница, определяющая тип строки, получаемой на вход. При указании константы CP_WINANSI данная строка рассматривается как строка ANSI. Если указать константу CP_WINUNICODE, то строка рассматривается как состоящая из символов Unicode.

Функция возвращает идентификатор, который библиотека DDEML присвоила данной строке.

В качестве параметров функция получает следующее:

  • idInst - программный идентификатор приложения, полученный при регистрации в библиотеке DDEML;
  • hsz - идентификатор строки.

Функция возвращает значение true, если операция прошла успешно, и false - если при выполнении функции произошли ошибки.

Для того, чтобы получить строку по ее идентификатору, необходимо воспользоваться функцией DdeQueryString:

В качестве параметров функция получает следующее:

  • idInst - программный идентификатор приложения, полученный при регистрации в библиотеке DDEML;
  • hsz - идентификатор строки, которую нужно получить.
  • psz - указательна буфер, в который будет записана строка
  • cchMax - максимальная длина строки в символах. Вид символа определяется следующим по порядку параметром и может быть ANSI (1 байт) или Unicode (2 байта)
  • iCodePage - определяет тип символов строки. Возможные значения CP_WINANSI - для символов стандарта ANSI (1 байт) и CP_WINUNICODE - для символов стандарта Unicode (2 байта).

Функция возвращает количество скопированных символов. При этом если фактическая длина строки (в символах) меньше указанной в параметре cchMax, то функция скопирует cchMax символов и вернет это значение. Если cchMax больше фактической длины строки, то функция скопирует всю строку и вернет количество скопированных символов. Если передать через параметр psz нулевое значение, то функция проигнорирует значение параметра cchMax и вернет фактическую длину строки в символах. Размер буфера в байтах для строки зависит от размера символа и определяется параметром iCodePage.

Для получения данных из глобальной области памяти по их идентификатору нужно воспользоваться функцией DdeGetData:

Функция должна получить на вход следующие параметры:

  • hData - идентификатор порции данных в глобальной области памяти;
  • pDst - указатель на буфер, куда будут скопированы данные из глобальной области.
  • cbMax - размер буфера в байтах. Если фактический размер данных больше размера области в буфере, которая выделяется под эти данные(см. ниже параметр cbOff), то будут скопированы только первые (cbMax - cbOff) байт. Иначе функция скопирует все данные в буфер.
  • cbOff - смещение в буфере относительно начала, с которого функция поместит в буфер данные из глобальной области.

Функция возвратит количество фактически скопированных байт данных. Если вместо ссылки на буфер через параметр pDst передать нулевое значение, то функция вернет фактический размер порции данных в глобальной области памяти, при этом значение параметров cbMax и cbOff будут проигнорированы.

Канал связи DDE создается с помощью функции DdeConnect:

В качестве параметров функция должна получить следующее:

  • idInst - программный идентификатор приложения, полученный при регистрации в библиотеке DDEML;
  • hszService - идентификатор строки названия сервиса, который необходимо предварительно получить вызовом функции DdeCreateStringHandle
  • hszTopic - идентификатор строки названия раздела, который также заранее запрашивается у библиотеки DDEML вызовом функции DdeCreateStringHandle;
  • pCC - указатель на специальную структуру типа CONVCONTEXT, в которой указывается информация о национальном языке и кодовой странице. В большинстве случаев (в нашем тоже) достаточно указать нулевое значение, что означает использование кодовой страницы ANSI.

Функция возвращает идентификатор созданного канала связи. В случае ошибки функция вернет нулевое значение. Полученный идентификатор канала необходимо хранить в течение всего сеанса связи.

Когда приложение завершает работу с каналом, оно должно закрыть его, вызвав функцию

DdeDisconnect:

В качестве параметра функция получает идентификатор канала, который нужно закрыть. Функция возвращает true, если канал успешно закрыт и false в случая возникновения ошибок при закрытии канала.

Функция обратного вызова имеет следующий заголовок:

  • wType - Код транзакции. Коды транзакций предопределены протоколом DDE. Значения и названия соответствующих им констант можно посмотреть в технической документации. Забегая вперед, отмечу, что в нашем примере будут использоваться транзакции XTYP_ADVSTART для запуска потока данных по каналу, XTYP_ADVSTOP - для остановки потока данных, XTYP_ADVDATA - транзакция с уведомлением наличии данных от сервера.
  • wFmt - формат данных (в нашем случае данные представляют собой текстовую строку, поэтому этому параметру при вызове будет присвоено значение CF_TEXT, равное единице).
  • hConv - идентификатор канала. Этот идентификатор получен при создании канала.
  • hsz1 - идентификатор строки названия раздела.
  • hsz2 - идентификатор строки названия элемента данных.
  • hData - идентификатор глобальной области в памяти, где находятся данные от сервера. Данные необходимо получить с помощью функции DdeGetData.

В свою очередь функция запуска транзакции DdeClientTransaction имеет следующий заголовок:

  • pData - ссылка на данные, передаваемые транзакцией.
  • cbData - размер передаваемых данных
  • hConv - идентификатор канала связи, полученный заранее функцией DdeConnect
  • hszItem - идентификатор элемента данных, в нашем случае - ячейки. Идентификатор должен быть получен заранее, с помощью функции DdeCreateStringHandle.
  • uFmt - формат данных. Для случая с Excel указывается константа CF_TEXT(1)
  • uType - код транзакции. Определяется комбинацией битовых флагов. В случае организации горячего канала выполняется транзакция XTYP_ADVSTART - для начала цикла получения данных из ячейки (подписки на ячейку) и XTYP_ADVSTOP - для прекращения цикла получения данных из ячейки (отписки от ячейки).
  • dwTimeout - тайм-аут для синхронных транзакций - максимальное время выполнения синхронной транзакции. Если в качестве параметра передать 0, то будет запущена асинхронная транзакция. При запуске синхронной транзакции, приложение ждет ее завершения. При этом максимальное время выполнения транзакции определяется значением параметра. При запуске асинхронной транзакции приложение не ждет завершения транзакции и продолжает свою работу. По завершению транзакции клиент получит транзакцию XTYP_XACT_COMPLETE.
  • pdwResult - ссылка на двойное слово, в которое будет записан код завершения транзакции. Изначально эта переменная должна быть приравнена к нулю. (По рекомендации Microsoft, не рекомендуется использовать этот параметр, так как, возможно, в дальнейшем он поддерживаться не будет).

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

Для функции обратного вызова необходимо создать делегат, который имеет соответствующую сигнатуру, и указать его в качестве параметра в функции DdeInitialize:

Забегая вперед, отмечу, что для отображения необходимых функций и констант библиотеки DDEML в компоненте ExcelDDEHotConnection служит класс DDEML.

Ниже приведен список остальных функций для работы с DDE:

Делегат функции обратного вызова:

Отображение функции DdeInitialize:

Отображение функции DdeUninitialize:

Отображение функции DdeCreateStringHandle:

Отображение функции DdeFreeStringHandle:

Отображение функции DdeConnect:

Отображение функции DdeDisconnect:

Отображение функции DdeClientTransaction:

Отображение функции DdeGetData:

Отображение функции DdeQueryString:

4. Организация горячего канала Excel - приложение DDE.

В этой главе вкратце описано, как осуществить корректное подключение и отключение от ячеек Excel. Например, необходимо получить доступ к ячейке, расположенной во втором столбце и первой строке на странице с названием <Лист1> рабочей книги <Книга1>. Для начала необходимо зарегистрироваться в библиотеке DDEML и получить программный идентификатор idInst:

После этого создаем канал связи с нужным разделом. В нашем случае, как было упомянуто выше, название сервиса: <EXCEL>, а название раздела <[Книга1.xls]Лист1>. Необходимо помнить, что расширение файла необходимо указывать, если эта книга открыта из файла. Если осуществляется подключение к созданной, но еще не сохраненной книге, то расширение не указывается.

После создания канала информируем Excel о том, чтобы приложение получало содержимое нужной ячейки, как только оно изменится (<горячий канал>). Для этого посылаем Excel транзакцию XTYP_ADVSTART:

Отключение производим в обратном порядке, сначала информируем сервер о том, что данные из ячейки нам больше не нужны, посылая Excel транзакцию XTYP_ADVSTOP:

После завершения транзакции, закрываем канал:

И завершаем работу с библиотекой DDEML:

5. Компонент ExcelDDEConnection.

Ниже приведены основные методы и свойства класса ExcelDDEHotConnection:

НазваниеОписание
ExcelDDEHotConnection()Конструктор. Осуществляет регистрацию в библиотеке DDEML
TopicDescriptorCollection TopicsСвойство. Ссылка на коллекцию разделов. Раздел адресуется названием книги и названием страницы
void Dispose()Завершить работу объекта. Закрывает все каналы и производит отключение от библиотеки DDEML
event AdviseDelegate DataСобытие. Происходит при изменении содержимого любой из подписанных ячеек. Событие вызывается для каждой изменившейся ячейки.

Коллекция разделов TopicDescriptorCollection.

Коллекция разделов представляет собой набор объектов, описывающий разделы. При добавлении раздела в коллекцию, происходит автоматическое создание канала, а при удалении - закрытие канала. Коллекция не допускает дублирование одинаковых разделов. Раздел добавляется в коллекцию только в том случае, если удалось создать канал для этого раздела.

Дескриптор раздела TopicDescriptor.

Экземпляр класса описывает раздел данных. Каждый раздел содержит в себе коллекцию элементов данных типа ItemDescriptor, описывающих ячейки. При добавлении ячейки происходит отправка Excel транзакции на подписку на эту ячейку, при удалении - транзакция на завершение работы с ячейкой.


Запрос значения атрибута R


Запрос значений других атрибутов


Задание значений атрибутов

При обмене с локальным МРВ из приложения – DDE-клиента – возможно:


чтение атрибута (0, R) каналов (в режиме REQUEST или ADVISE);


чтение (REQUEST) и запись (POKE) любых других атрибутов каналов.

Запись значений в атрибуты, вычисляемые в канале, не имеет смысла.

Если в узле существуют каналы с одинаковым именем, то выполнение запроса влияет только на канал с наименьшим ID.

Если клиентом DDE является Excel, то DDE-обмен с МРВ может быть сконфигурирован с помощью формул Excel и/или макросов VBA Формула Excel может быть использована только для запроса значения (в режиме ADVISE или REQUEST) – в этом случае она имеет следующий формат:

=<server>|<topic>!<item>

server – имя сервера в формате RTM<k>, где k – индивидуальный номер узла;

topic – тема запроса (см. примеры ниже);

item – имя канала или уточненное имя атрибута.

Уточненное имя атрибута имеет следующий формат:

<имя канала>.<номер атрибута>

Любой из перечисленных параметров DDE-формулы Excel следует заключить в одинарные кавычки в следующих случаях:


если параметр содержит пробелы или служебные символы, которые используются в формулах Excel (двоеточие, минус и т.п.);


если параметр имеет вид ссылки на ячейку (примером такого параметра может служить имя канала ch1).

В приведенных ниже примерах узел имеет индивидуальный номер 2.

Запрос значения атрибута R

Для запроса реального значения канала pila в режиме ADVISE в ячейку таблицы Excel нужно записать следующую формулу:

В этом режиме значение в ячейке обновляется автоматически.

В режиме ADVISE монитор посылает клиенту значение канала при каждом его пересчете.

Для запроса реального значения канала pila в режиме REQUEST в ячейку таблицы Excel нужно записать одну из следующих формул:

Во второй формуле тема запроса может быть произвольной. В этом режиме значение канала запрашивается и записывается в ячейку однократно при исполнении формулы.

Запросить значение атрибута (0, R) канала в режиме REQUEST можно также с помощью одного из следующих макросов VBA Excel (во втором макросе тема запроса может быть произвольной):

'PUT or GET to read R

chNum = Application.DDEInitiate("RTM2", "GET")

Worksheets("Sheet1").Range("F1") = Application.DDERequest(chNum, "pila")

chNum = Application.DDEInitiate("RTM2", "LL")

Worksheets("Sheet1").Range("F1") = Application.DDERequest(chNum, "pila.0")

Запрос значений других атрибутов

Для запроса значения атрибутов (3, C), (4, I), (7, P); (8, W), (26, HL), (27, LL), (28, HA), (29, LA), (30, HW), (31, LW), (79, CODE) и (127, NAME) могут быть использованы запросы двух видов:


topic – короткое имя атрибута, item – имя канала;


topic – произвольное значение (из допустимых), item – уточненное имя атрибута.

Для запроса значений других атрибутов могут быть использованы запросы только второго вида.

Таким образом, для запроса, например, верхнего предела (26, HL) канала ch1 в ячейку таблицы Excel нужно записать одну из следующих формул:

Запросить значение атрибута из приведенного выше перечня (ниже в примерах запрашивается кодировка) можно также с помощью одного из следующих макросов (для запроса значений других атрибутов нужно использовать второй макрос):

'Short name to read attribute

chNum = Application.DDEInitiate("RTM2", "CODE")

Worksheets("Sheet1").Range("F1") = Application.DDERequest(chNum, "ch1")

chNum = Application.DDEInitiate("RTM2", "LL")

Worksheets("Sheet1").Range("F1") = Application.DDERequest(chNum, "ch1.79")

Задание значений атрибутов

Для задания значения атрибутов (2, In), (3, C), (4, I), (7, P); (8, W), (26, HL), (27, LL), (28, HA), (29, LA), (30, HW), (31, LW), (79, CODE) и (127, NAME) могут быть использованы макросы двух видов:


topic – короткое имя атрибута, item – имя канала;


topic – произвольное значение (из допустимых), item – уточненное имя атрибута.

Для задания значений других атрибутов могут быть использованы макросы только второго вида.

Таким образом, для записи в атрибут (2, In) канала ch1 значения из ячейки C3 таблицы Excel можно использовать один из следующих макросов:


Эта статья является частью серии «Fileless Malware». Все остальные части серии:

Кто-нибудь еще помнит DDE? Вероятно, немногие. Это был один из первых протоколов взаимодействия между процессами, который позволял приложениям и устройствам передавать данные.

Я сам немного знаком с ним, потому что раньше я проверял и тестировал телеком-оборудование. В то время DDE позволял, например, передавать для операторов колл-центров идентификатор звонящего абонента в CRM приложение, которое в конечном итоге открывало карточку клиента. Для этого вы должны были подключить кабель RS-232 между телефоном и компьютером. Вот были деньки!

Как оказалось, Microsoft Word все еще поддерживает DDE.

Что делает эту атаку эффективной без кода, так это то, что вы можете получить доступ к протоколу DDE непосредственно из автоматических полей документа Word (снимаю шляпу перед SensePost за исследования и публикации об этом).

Коды полей – это еще одна древняя функция MS Word, которая позволяет добавлять динамический текст и немного программирования в документ. В качестве самого очевидного примера можно привести поле «номер страницы», который можно вставить в нижний колонтитул с помощью значения . Это позволяет автоматическим образом генерировать номера страниц.



Подсказка: вы сможете найти пункт меню Полe (Field) в разделе Вставка (Insert)

Я помню, что когда впервые обнаружил эту возможность в Word, то был поражен. И вот пока патч не отключил ее, Word так и поддерживал параметр полей DDE. Идея состояла в том, что DDE позволит Word общаться с приложением напрямую, для возможности затем передать выходные данные программы в документ. Это была совсем юная технология в то время – поддержка обмена данными с внешними приложениями. Позже она была развита в технологии COM, которую мы также рассмотрим ниже.

В итоге, хакеры поняли, что этим приложением DDE может быть командная оболочка, которая, конечно же, запускает PowerShell, а оттуда хакеры могут делать всё, что им угодно.
На скриншоте ниже видно, как я использовал данную скрытную технику: маленький сценарий PowerShell (далее – PS) из поля DDE загружает другой PS скрипт, который запускает вторую фазу атаки.



Спасибо Windows за всплывающее предупреждение, о том что встроенное поле DDEAUTO скрытно пытается запустить оболочку

Предпочтительным методом эксплуатации уязвимости является использование варианта с полем DDEAUTO, которое автоматически запускает сценарий при открытии документа Word.
Давайте подумаем, что с этим можно сделать.



Оболочка была запущена без малейшего кодирования. Даже ребенок сможет это сделать!

DDE и поля

Позже Microsoft все-таки отключила DDE в Word, но перед этим компания заявила, что эта функция была просто неправильно использована. Их нежелание что-то менять понятно. Из своего опыта я сам наблюдал такой пример, что обновление полей при открытии документа было включено, но макросы Word были отключены ИТ-службой (но с показом уведомления). Кстати, соответствующие параметры вы сможете найти в разделе настроек Word.

Однако, даже если обновление полей включено, Microsoft Word дополнительно уведомляет пользователя, когда поле запрашивает доступ к удаленным данным, как в случае с DDE выше. Microsoft действительно предупреждает вас.

Но скорее всего, пользователи все равно пропустят это предупреждение и активируют обновление полей в Word. Это одна из редких возможностей поблагодарить Microsoft за отключение опасной функции DDE.

Насколько трудно сегодня найти непропатченную систему Windows?

Для этого тестирования я использовал среду AWS Workspaces для получения доступа к виртуальному рабочему столу. Таким образом я получил непропатченную виртуальную машину с MS Office, которая позволила мне вставить поле DDEAUTO. Не сомневаюсь, что подобным же образом можно найти и другие компании, которые до сих пор не установили нужные патчи безопасности.

Тайна предметов

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

Чтобы понять этот сценарий, давайте вспомним Модель компонентного объекта Microsoft, или сокращенно COM (Component Object Model).

COM существует с 1990-х годов, и определяется как «нейтральная к языку программирования объектно-ориентированная модель компонентов» на основе удаленных вызовов процедур RPC. Для общего понимания терминологии COM прочтите этот пост на StackOverflow.

По большому счету, вы можете представить приложение COM как исполняемый файл Excel или Word, или какой-либо другой запускаемый бинарный файл.

Оказывается, COM-приложение также может запускать сценарий — JavaScript или VBScript. Технически это называется скриптлет. Возможно, вы встречали расширение.sct у файлов в Windows – это и есть официальное расширение для скриплетов. По сути, они являются кодом скрипта, заключенного в XML обертку:


Хакеры и пентестеры обнаружили, что есть отдельные утилиты и приложения в Windows, которые принимают COM-объекты и, соответственно, скриптлеты тоже.

Я могу передать скриптлет в утилиту Windows, написанную на VBS, известную как pubprn. Она находится в недрах C:\Windows\system32\Printing_Admin_Scripts. Кстати, есть и другие утилиты Windows, которые принимают объекты в качестве параметров. Для начала рассмотрим этот пример.

В следующем посте я объясню, как скриптлеты COM могут быть использованы хакерами с помощью таблиц Excel.

Вам в качестве домашней работы – посмотреть это видео с Derbycon 2016 года, которое объясняет, как именно хакеры использовали скриптлеты. А также прочитать эту статью про скриптлеты и какой-то моникер.

Читайте также: