Руби RBE! Изучаем защиту плагинов SketchUр, написанных на Ruby

Скрип­товый язык Ruby исполь­зует­ся для написа­ния пла­гинов во мно­гих прик­ладных прог­раммах. Одна из них — 3D-редак­тор SketchUp. Сегод­ня мы изу­чим внут­реннос­ти таких рас­ширений, зашиф­рован­ных с исполь­зовани­ем тех­нологии RBE, и напишем свой кон­вертер из фор­мата RBE в RB.

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

Из­началь­но мно­гие скрип­товые язы­ки раз­рабаты­вались имен­но как язы­ки для опи­сания логики рас­ширений популяр­ных прог­рамм и слу­жили для авто­мати­зации нес­ложных рутин­ных дей­ствий. Исполь­зовать их дол­жны были прос­тые поль­зовате­ли, не слиш­ком иску­шен­ные в прог­рамми­рова­нии. Некото­рые язы­ки слу­жат в этом качес­тве до сих пор (подоб­ные слу­чаи опи­саны в стать­ях «Бе­зум­ный Max. Как лома­ют пла­гины для 3ds Max» и «Пат­чим JSXBIN. Как пра­вить бинар­ные скрип­ты Adobe без переком­пиляции»), что порож­дает спрос на защиту их откры­того кода от иссле­дова­ния и модифи­кации.

Ruby в этом пла­не не исклю­чение: он активно исполь­зует­ся для прог­рамми­рова­ния рас­ширений и пла­гинов. Сегод­ня мы рас­смот­рим его при­мене­ние в прог­рамме SketchUp. SketchUp — это популяр­ный пакет соз­дания 3D-гра­фики «для чай­ников», так ска­зать 3ds Max на минимал­ках. За вре­мя сво­его сущес­тво­вания он успел побывать в собс­твен­ности у Google, а потом был про­дан по непонят­ным при­чинам.

Так уж повелось, что язы­ковой осно­вой скрип­тового API (опи­сание инте­ресу­ющиеся могут най­ти на офи­циаль­ном сай­те SketchUp) стал имен­но язык Ruby, на котором мож­но писать как прос­тецкие мак­росы, хра­нящи­еся в тек­сто­вых фай­лах со стан­дар­тным рас­ширени­ем .rb, так и прод­винутые кросс‑плат­формен­ные пла­гины с рас­ширени­ем .rbz. При соз­дании это­го фор­мата прог­раммис­ты SketchUp осо­бо не замора­чива­лись и пош­ли по самому прос­тому про­торен­ному пути — пла­гины явля­ются, по сути, ZIP-архи­вами, в которых, помимо клас­сов Ruby, может содер­жать­ся мно­жес­тво дру­гих фай­лов: тек­сты, изоб­ражения, даже натив­ные бинар­ники под раз­ные плат­формы с рас­ширени­ями .so и .bundle. Их мож­но сер­тифици­ровать (для авто­ризо­ван­ных раз­работ­чиков), а мож­но забить на это и исполь­зовать так.

Ра­зуме­ется, прог­раммис­ты про­дума­ли и встро­или механизм защиты кода клас­сов от иссле­дова­ния. Здесь авто­ры тоже полени­лись и вмес­то того, что­бы (как мно­гие прод­винутые раз­работ­чики) пре­обра­зовать Ruby-текст в шитый код вир­туаль­ной машины, не мудрствуя лукаво прос­то пошиф­ровали его стан­дар­тным крип­тоал­горит­мом. Пер­воначаль­но для это­го был при­думан фор­мат .rbs («scrambled»).

Нес­мотря на то что про­цесс шиф­рования выпол­нялся на уда­лен­ном сер­вере раз­работ­чиков, алго­ритм дос­таточ­но быс­тро стал сек­ретом Полиши­неля. Более того, энту­зиас­ты написа­ли целый выводок «скрам­бле­ров/анс­крам­бле­ров» (нап­ример, RbsUnscrambler), ведь шиф­рование тек­ста про­води­лось c исполь­зовани­ем баналь­ного сим­метрич­ного алго­рит­ма Blowfish, который допус­кает крип­тование в обе сто­роны.

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

Итак, закан­чива­ем с теорией и перехо­дим к прак­тике. Допус­тим, у нас име­ется некий пла­гин к SketchUp в фор­мате .rbz. Рас­паковав его при помощи WinZip, видим мно­жес­тво фай­лов клас­сов с рас­ширени­ем .rbe. Бинар­ное содер­жимое таких фай­лов для иссле­дова­ний не под­ходит — как видишь, внут­ри высоко­энтро­пий­ный белый шум, отли­чающий­ся от .rbs толь­ко вер­сией сиг­натуры RBS2.0.

Пос­коль­ку кон­верте­ры из фор­мата RB в RBE и обратно, как я уже говорил, в пуб­личном дос­тупе пока отсутс­тву­ют, поп­робу­ем отсле­дить рас­шифров­ку такого кода при заг­рузке пла­гина в динами­ке. Путем нес­ложных манипу­ляций с ProcMon опре­деля­ем, что при запус­ке SketchUp он заг­ружа­ет рас­пакован­ные клас­сы и про­чие биб­лиоте­ки пла­гина из это­го катало­га:

C:Users...AppDataRoamingSketchUpSketchUp...SketchUpPlugins

Поп­робу­ем пой­мать эту заг­рузку при помощи нашего любимо­го отладчи­ка x64dbg.

Обыч­но в подоб­ных слу­чаях мы ста­вим точ­ки оста­нова на сис­темных фун­кци­ях откры­тия и чте­ния фай­лов CreateFile и ReadFile, одна­ко этот путь вне­зап­но ока­зыва­ется очень тер­нистым. SketchUp, как и 3ds Max, в опре­делен­ной сте­пени сра­жает­ся с отладчи­ком — при дол­гой отладке, мно­гок­ратном сра­баты­вании точек оста­нова и даже атта­че к готово­му запущен­ному про­цес­су он так и норовит «замер­знуть», что откро­вен­но вымора­жива­ет уже нас самих. Что­бы не тра­тить собс­твен­ные нер­вные клет­ки, поп­робу­ем зай­ти с дру­гой сто­роны.

Как я уже упо­минал, 6-бай­товые сиг­натуры зак­рипто­ван­ных фай­лов хорошо извес­тны (RBS1.0 для .rbs и RBS2.0 для .rbe). Поп­робу­ем поис­кать стро­ку RBS2.0 по всем заг­ружен­ным модулям пакета SketchUp. Доволь­но быс­тро мы находим ее в глав­ном модуле SketchUp.exe по RVA=0x1D72F9C. Открыв дизас­сем­бли­рован­ный код в IDA, мы убе­дим­ся, что алго­ритм шиф­рования на этот раз RSA + AES.

Пе­рей­дя по цепоч­ке ссы­лок на эту стро­ку, обна­ружи­ваем фун­кцию, воз­вра­щающую тип шиф­рования Ruby-кода: sub_141347340.

Как видим, воз­вра­щаемое зна­чение 1 соот­ветс­тву­ет ста­рому типу шиф­рования .rbs, а 2 — новому .rbe. Изу­чив ссыл­ки на sub_141347340, находим фун­кцию, рас­шифро­выва­ющую этот самый тип 2, — sub_141347F20.

От­крыв реали­зацию этой фун­кции, мы видим под­твержде­ние наших пред­положе­ний: для рас­шифров­ки кода SketchUp обра­щает­ся к Microsoft CryptoAPI, вызывая крип­топро­вай­дер Microsoft Enhanced RSA and AES Cryptographic Provider, при помощи которо­го и рас­шифро­выва­ет содер­жимое фай­ла стан­дар­тной биб­лиотеч­ной фун­кци­ей CryptDecrypt.

Источник: xakep.ru

Ответить

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