История боевого трояна Stuxnet не закончилась атакой на военный завод в Иране, где тайно производилось ядерное оружие. Осенью прошлого года специалисты по безопасности обнаружили троян Duqu, в коде которого узнаётся почерк загадочных авторов Stuxnet. Duqu оказался не менее интересным объектом для изучения: достаточно сказать, что один из его компонентов написан на языке программирования, который не удалось опознать аналитикам «Лаборатории Касперского».
Сейчас почти никто не ставит под сомнение то, что целью Stuxnet было разрушение промышленной линии, предположительно использующейся для незаконного производства ядерного оружия. Несмотря на отсутствие непосредственных доказательств, антивирусные компании собрали достаточно доводов в пользу этой версии. Вот что было известно в ноябре 2010 года:
По сведениям Symantec, червь Stuxnet разыскивал специфические промышленные преобразователи частоты, производимые только двумя компаниями: одна в Финляндии, другая — в Иране. Программа следила за работой преобразователей, и если частота оказывалась в диапазоне от 807 до 1210 герц, брала управление на себя. Частотные преобразователи могут использоваться для чего угодно, но такая высокая частота указывает на одно конкретное применение — центрифуги для обогащения урана.
Захватив контроль над центрифугами, троян давал им такие команды, которые приводили к повреждению оборудования.
Что из этого следует? Во-первых, авторы Stuxnet располагали подробной информацией о том, как устроен секретный иранский завод, какое программное обеспечение там используется и как настроено оборудование. Во-вторых, у них были ресурсы для отладки своей программы, для чего желательно иметь в распоряжении те самые редкие центрифуги.
В мире не так уж много организаций, способных соорудить промышленную линию для обогащения урана ради того, чтобы отладить троян, и при этом знакомых с иранскими секретами. Очевидно, что Stuxnet не мог быть делом рук одиночки. Скорее всего, он был создан при участии спецслужб одной из враждебных Ирану стран.
В отличие от Stuxnet, Duqu разработан для той же задачи, с которой справляются и менее замысловатые трояны, — для кражи конфиденциальной информации с компьютеров пользователей. Если Stuxnet — это киллер, то Duqu — это разведчик, собирающий информацию для подготовки следующего удара, а затем заметающий следы (последнее — чистая правда: спустя 36 дней после заражения троян удаляет себя).
Интересная деталь: по всей видимости, Duqu не способен распространяться самостоятельно. В конце ноября 2011 года компания Symantec сообщала о том, что зафиксировала всего шесть случаев заражения: два — в Иране и по одному в Индии, Судане и Вьетнаме. Кроме того, заражены компьютеры во Франции, Нидерландах, Швейцарии и Украине, принадлежащие одной и той же компании или организации. Другие антивирусные компании фиксировали заражения в Австрии, Венгрии, Индонезии, Великобритании и ещё несколько опять-таки в Иране.
В Symantec считают, что авторы Duqu имели доступ к исходному коду Stuxnet. Некоторые части Duqu очень похожи на Stuxnet, однако компонентов, предназначенных для взаимодействия с системой управления предприятием, в нём нет. Вместо них троян снабжён средствами для сбора информации о компьютере и записи нажатий на клавиши (keylogger).
Фрагмент, написанный на неизвестном языке программирования, скрывался как раз в той части трояна, которая отличает Duqu от Stuxnet. Он заведовал взаимодействием между заражённой машиной и командным сервером Duqu. Седьмого марта «Лаборатория Касперского» обратилась к сетевому сообществу и попросила помочь определить происхождение кода, который в компании окрестили «Фреймворком Duqu»:
В коде Фреймворка Duqu прослеживаются явные особенности:
- Весь функционал реализуют объекты.
- Таблица функций объекта находится непосредственно в его памяти и может быть изменена в процессе выполнения.
- Нет явных отличий между классами, которые можно было бы отнести к какой-либо стандартной библиотеке (связные списки, хэш-таблицы), и классами троянца.
- Объекты общаются между собой с помощью прямых вызовов их методов, отложенных вызовов и объектов для обратного вызова по событию.
- Не используются функции стандартных библиотек, при этом активно используются функции Windows API.
Все объекты являются экземплярами какого-либо класса, мы обнаружили в коде 60 различных классов. Каждый объект создаётся с помощью функции-конструктора, которая выделяет память, заполняет таблицу функций и инициализирует поля.
Расположение полей в памяти объекта зависит от конкретного класса. Например, не у всех классов таблица функций находится в начале. При этом у некоторых классов бинарно совместимы таблицы функций, но прямых указаний на наличие у них общего класса-предка, как в других объектно-ориентированных языках, не обнаруживается.
Объекты удаляются с помощью функций-деструкторов. Типичный деструктор удаляет объекты-поля, затем освобождает память самого объекта.
Методы классов могут вызываться по указателю из таблицы функций (аналогично «виртуальным» функциям C++) или напрямую. В большинстве объектно-ориентированных языков методы получают параметр «this», при этом порядок передачи этого параметра обычно фиксирован — в определенном регистре или параметре в стеке. Однако для классов Фреймворка Duqu этот порядок не фиксирован — параметр может передаваться в любом регистре или в стеке.
Реализация и содержание объектов в Фреймворке Duqu не совместимы с объектами C++, которые используются во всех других компонентах Duqu. Однако есть ещё одна особенность, которая активно используется во Фреймворке, — парадигма событийно-ориентированного программирования.
Если все остальные компоненты Duqu были написаны на C++, то для «Фреймворка» определённо использовался какой-то другой язык программирования. В «Лаборатории Касперского» перебрали и отбросили множество вариантов. Все языки и компиляторы, которые они испытали, — Objective C, D, Go, Java, Ada, Python, Lua, Haskell, Erlang — генерировали код, совершенно непохожий на код Duqu.
Обращение к сообществу было верным шагом. Большинство предложенных идей оказались ошибочными, но в итоге кому-то удалось набрести на зацепку. Сначала один из комментаторов предположил, что код всё же сгенерирован Visual Studio: в дизассемблированном коде прослеживались характерные особенности компилятора Microsoft. Однако это не C++ и не обычный Си, а, как подсказал кто-то ещё, один из объектно-ориентированных диалектов Си.
Сегодня эксперт «Лаборатории Касперского» отчитался в блоге компании о разгадке тайны «Фреймворка Duqu»:
После нескольких экспериментов с различными версиями MSVC и опциями компиляции мне удалось воспроизвести код функции конструктора, о котором я писал в предыдущем посте, и получить из этого кода бинарный код, совпадающий с найденным в Duqu.
При компиляции указанного выше кода на Си с помощью компилятора из поставки MSVC 2008 с опциями /O1 (оптимизация по размеру) и /Ob1 (разворачивать только __inline функции) получается машинный код, совпадающий с оригинальным кодом этой функции в Duqu. Следует заметить, что другие опции компиляции, а также изменение порядка операции и if/else блоков изменяет конечный код; компилятор MSVC 2005 также генерирует другой код. Из этого следует, что, скорее всего, Фреймворк Duqu был скомпилирован MSVC 2008 с опциями /O1 /Ob1 из исходного текста на языке С.
Наиболее похожая объектно-ориентированная надстройка над Си, имеющая открытые исходные коды, называется SOO, однако в «Лаборатории Касперского» сомневаются, что использовалась именно она. SOO — слишком новый проект. Его исходники ещё не были опубликованы, когда шла работа над Duqu (в этом месте любители теорий заговоров заметили бы, что одно другому не мешает и не вредно было бы присмотреться к автору SOO повнимательнее, но мы не любители теорий заговора, нет).
Напрашиваются два вывода. Во-первых, авторство «Фреймворк Duqu» принадлежит отдельной группе разработчиков, иначе объяснить такое разительное отличие «Фреймворка» от остальных компонентов нечем. Во-вторых, как замечает Игорь Суменков из «Лаборатории Касперского», эта группа, скорее всего, состоит из профессионалов, который используют наработки программистов «старой школы» с многолетним опытом работы.
Развязка несколько разочаровывает. Cи с замысловатым препроцессором не столь интересен, как неизвестный язык программирования. Впрочем, даже так эта история остаётся более захватывающей, чем обычные истории про вирусы, — особенно истории того сорта, где текст перемежается с ассемблером.