Вирус-майнер с “Heaven’s Gate”

Автор оригинала: hasherezade
  • Перевод
Всем привет! В преддверии старта нового потока по курсу «Реверс-инжиниринг» делимся с вами переводом очень интересного материала. Приятного прочтения




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

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

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

Однако время от времени мы находим майнеры, использующие интересные трюки. Недавно мы наблюдали технику, которая называется “Heaven’s Gate”, она позволяет делать инъекции в 64-разрядные процессы из 32-разрядных загрузчиков. Эта идея не нова, ее первая реализация датируется 2009 годом, но любопытно посмотреть, как она реализована в новом виде, полученном прямо «из дикой природы».

Новички в анализе вирусов могут почитать гайд о том, что такое Heaven’s Gate и как подходить к его анализу.

Материалы для анализа



Этот образец был найден в продолжении кампании Ngay (подробнее об этом здесь). Проверка биографии подобных образцов привела меня к статье @_qaz_qaz, которая описывает более раннюю кампанию с аналогичным образцом. Однако его анализ не включал в себя технологию Heaven’s Gate.


Анализ поведения


Чтобы увидеть упомянутую инъекцию, мы должны запустить образец на 64-разрядной системе. Мы видим, что он запускает сущность блокнота, с параметрами, характерными для майнинга криптовалюты:



Взглянув на строки в памяти в ProcessExplorer, мы увидим, что это не настоящий блокнот, а майнер XMRig Monero.



Итак, на данный момент мы уверены, что изображение блокнота в памяти было заменено скорее всего методом RunPE (Process Hollowing).

Основной дроппер 32-х разрядный, но перекладывает полезную нагрузку на 64-х разрядный блокнот:



Самое интересное, что этот тип инъекции не поддерживается официальным API Windows. Мы можем читать/писать в память 32-разрядных процессов из 64-разрядного приложения (используя WoW64 API), но не наоборот.

Однако есть некоторые неофициальные решения, например, как техника под названием “Heaven’s Gate.”

Обзор Heaven’s Gate


Техника “Heaven’s Gate” была впервые описана в 2009 году хакером с никнеймом Roy G. Biv. Позже было создано много реализаций, например библиотека Wow64ext или, основанная на ней, W64oWoW64. В своем блоге в 2015 году Алекс Ионеску описал меры борьбы с этой техникой.
Давайте посмотрим на то, как она работает.

Запуск 32-разрядных процессов на 64-разрядной Windows


Каждый 32-разрядный процесс, выполняемый в 64-разрядной версии Windows, выполняется в специальной подсистеме WoW64, которая эмулирует 32-разрядную среду. Можно провести аналогию с 32-разрядной песочницей, которая создается внутри 64-разрядного процесса. Итак, сначала создается 64-разрядная среда для процесса. А уже внутри нее создается 32-разрядная среда. Приложение выполняется в этой 32-разрядной среде, но не имеет доступа к 64-разрядной ее части.

Если мы просканируем 32-разрядный процесс снаружи с помощью 64-разрядного сканера, мы увидим, что внутри себя он имеет как 32, так и 64-разрядные DLL. Самое главное, что он имеет две версии NTDLL: 32-разрядную (загружается из каталога SysWow64) и 64-разрядную (загружается из каталога System32):



Однако сам 32-разрядный процесс не видит 64-разрядную часть и ограничивается использованием 32-разрядных DLL. Чтобы сделать инъекцию в 64-разрядный процесс, нужно использовать 64-разрядные версии соответствующих функций.

Сегменты кода


Чтобы получить доступ к запретной части среды, нам нужно понять, как производится изоляция. Оказывается, все довольно просто. Выполнение 32- и 64-разрядного кода доступно через другой адрес сегмента кода: 32-разрядный — 0x23 и 64-разрядный — 0x33.

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

Внутри майнера: реализация Heaven’s Gate


Я не буду проводить полный анализ этого майнера, поскольку он уже был описан здесь. Давайте сразу перейдем к тому месту, где начинается самое интересное. Вредоносная программа проверяет свою среду, и если она обнаруживает, что работает на 64-разрядной системе, то использует другой путь, чтобы сделать инъекцию в 64-разрядный процесс:



После некоторых проверок анти-анализа, она создает новый, приостановленный 64-разрядный процесс (в данном случае это блокнот):



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

Во-первых, загрузчик передает обработку 64-разрядной NTDLL:



То, что происходит внутри функции get_ntdll требует более детального объяснения. В качестве пояснения мы также можем взглянуть на аналогичный код в библиотеке ReWolf.

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



Кажется, этот код был скопирован прямо из открытой библиотеки: https://github.com/rwfpl/rewolf-wow64ext/blob/master/src/internal.h#L26

Селектор сегмента 0х33 помещается в стек. Затем, вредоносная программа вызывает следующую строку: (таким образом адрес следующей строки также помещается в стек.)



Адрес, который был помещен в стек, фиксируется путем добавления 5 байт и устанавливается после retf:



В конце вызывается инструкция RETF. RETF – это “far return”, и в отличие от обычного RET, она позволяет указать не только адрес, с которого нужно продолжить выполнение, но и сегмент. В качестве аргументов он принимает два DWORD из стека. Таким образом, когда выполняется RETF, обратным адресом возврата становится:

0x33:0x402A50

Благодаря измененному сегменту код, начинающийся с указанного адреса, интерпретируется как 64-разрядный. Таким образом, код, который отладчик видит 32-разрядным…



… на самом деле 64-разрядный.

Для быстрого переключения представлений я использую функцию PE-bear:



И вот как выглядит этот фрагмент кода, если он интерпретируется как 64-разрядный:



Таким образом, код, который выполняется здесь отвечает за перемещение содержимого регистра R12 в переменную в стеке, а затем переключается обратно в 32-разрядный режим. Это делается с целью получения 64-битного Thread Information Block (TEB), из которого далее мы получаем 64-битный Process Environment Block (PEB) – смотрим на аналогичный код.

64-разрядный PEB используется в качестве отправной точки для поиска 64-разрядной версии NTDLL. Эта часть реализована достаточно тривиально («ванильную» реализацию этого метода можно найти здесь), с использованием указателя на загруженные библиотеки, которые являются одним из полей в структуре PEB. Итак, из PEB мы получаем поле под названием Ldr:



Ldr — это структура типа _PEB_LDR_DATA. Она содержит запись под названием InMemoryOrderModuleList:



Этот список содержит все загруженные библиотеки, которые присутствуют в памяти исследуемого процесса. Мы просматриваем список, пока не находим интересующую нас библиотеку, в нашем случае это NTDLL. Именно это и делает вышеупомянутая функция get_ntdll. Чтобы найти подходящее имя, она вызывает следующую функцию, обозначенную как is_ntdll_lib, которая сверяет по символам имя библиотеки с ntdll.dll. Получается эквивалент этого кода.



Если имена совпадают, то адрес библиотеки возвращается на пару регистров:



Как только мы нашли NTDLL, нам просто нужно получить адреса соответствующих функций. Мы сможем это сделать, просмотрев таблицу экспорта библиотеки:



Извлекаются следующие функции:

  • NttUnmapViewOfSection
  • NtGetContextThread
  • NtAllocateVirtualMemory
  • NtReadVirtualMemory
  • NtWriteVirtualMemory
  • NtSetContextThread.

Как мы знаем, эти функции типичны для техники RunPE. Сначала используется NtUnmapViewOfSection, чтобы анмапить (unmap) исходный PE-файл. Затем в удаленном процессе выделяется память и записывается новый PE. В конце контекст процесса изменяется, чтобы выполнение началось из внедренного модуля.

Адреса функций сохраняются и позже вызываются (аналогично этому коду) для управления удаленным процессом.

Заключение


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

Техника Heaven’s Gate существует уже несколько лет. Некоторые вредоносные программы используют ее с целью повышения скрытности. Но в случае этого майнера авторы, вероятно, стремились скорее максимизировать производительность, используя полезную нагрузку, которая лучше всего соответствует целевой архитектуре.

На этом все. А узнать подробнее о нашем курсе можно тут.
  • +20
  • 4,2k
  • 4
OTUS. Онлайн-образование
810,95
Цифровые навыки от ведущих экспертов
Поделиться публикацией

Похожие публикации

Комментарии 4

    +2
    Вполне возможно, что в 2018 году эта тенденция будет только расти.

    Ребят, боюсь расстроить вас, но уже 2019-й год подходит к концу.
      0
      Да то разве инъекция, вот инъекция была :)


        0
        Не это?
        image
          0

          Ну так фильм уже другой, в росте то про SG1 картинка :)

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

      Самое читаемое