Как распаковывать семейство программ ICEDID

ICEDID — это семейство вредоносных программ, обнаруженное в 2017 году исследователями IBM X-force и связанное с кражей учетных данных, банковской информации и другой личной информации. ICEDID всегда было распространенным семейством, но его рост стал еще больше после временного прекращения работы EMOTET в начале 2021 года. ICEDID был связан с распространением нескольких отдельных семейств вредоносных программ, включая DarkVNC и COBALT STRIKE. Регулярные отраслевые отчеты, в том числе исследовательские публикации, подобные этой, помогают смягчить эту угрозу. В данной статье рассмотрм как распаковывать семейство программ  ICEDID.

Настройка среды

В этом уроке мы используем Windows 10 и Python 3.10.

Elastic Security Labs выпускает набор инструментов для автоматизации процесса распаковки и помощи аналитикам и сообществу в реагировании на ICEDID.

Script Description Compatibility
decrypt_file.py Decrypt ICEDID encrypted file Windows and others (not tested)
gzip_variant/extract_gzip.py Extract payloads from ICEDID fake GZip file Windows and others (not tested)
gzip_variant/extract_payload_from_core.py Extract and decrypt payloads from the rebuilt ICEDID core binary Windows and others (not tested)
gzip_variant/load_core.py Load and execute core custom PE binary Windows only
gzip_variant/read_configuration.py Read ICEDID configuration file contained in the fake GZip Windows and others (not tested)
rebuild_pe.py Rebuild a PE from ICEDID custom PE file Windows and others (not tested)

 

Чтобы использовать эти инструменты, клонируйте репозиторий выпусков Elastic Security Lab и установите модуль NightMARE.

git clone https://github.com/elastic/labs-releases
cd labs-release
pip install .\nightMARE\

Здесь используется модуль NightMARE. Эта библиотека реализует различные алгоритмы, необходимые нам для распаковки различных полезных данных, встроенных в ICEDID. Мы выпускаем NightMARE, потому что он необходим для анализа ICEDID, но следите за обновлениями — по мере того, как мы продолжаем развивать и совершенствовать эту структуру, будет еще больше.

Распаковка поддельного GZip

Поддельный GZip ICEDID — это файл, который маскируется под действительный файл GZip, отформатированный путем инкапсуляции реальных данных с помощью заголовка и нижнего колонтитул GZip

GZip header and footer

Магические байты GZip отображаются красным цветом.

Заголовок GZip отображается зеленым цветом.

Фиктивное имя файла имеет синий цвет.

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

FakeGzip data structure

Мы будем использовать скрипт labs-releases\tools\icedid\gzip-variant\extract_gzip.py, чтобы распаковать этот мошеннический GZip.

usage: extract_gzip.py [--help] input output

positional arguments:
  input       Input file
  output      Output directory

options:
  -h, --help  show this help message and exit

Мы будем использовать extract_gzip.py в примере ICEDID, указанном выше, и сохраним содержимое в созданную нами папку под названием «extract» (вы можете использовать любую существующую выходную папку).

python extract_gzip.py 54d064799115f302a66220b3d0920c1158608a5ba76277666c4ac532b53e855f extract

============================================================
Fake Gzip
============================================================
is_dll: True
core: UponBetter/license.dat (354282 bytes)
stage_2: lake_x32.tmp (292352 bytes)

extract\configuration.bin
extract\license.dat
extract\lake_x32.tmp

Этот скрипт возвращает три отдельных файла, состоящих из:

  • Зашифрованный файл конфигурации: Configuration.bin.
  • Зашифрованный основной двоичный файл: License.dat.
  • Загрузчик персистентности: Lake_x32.tmp

Files extracted from the fake GZip

Расшифровка основных двоичных файлов и файлов конфигурации

Извлеченная нами конфигурация и основной двоичный файл зашифрованы с использованием специальной схемы шифрования ICEDID. Мы можем расшифровать их с помощью скрипта labs-releases\tools\icedid\decrypt_file.py.

usage: decompress_file.py [--help] input output

positional arguments:
  input       Input file
  output      Output file

options:
  -h, --help  show this help message and exit

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

python .\decrypt_file.py .\extract\license.dat .\extract\license.dat.decrypted

python .\decrypt_file.py .\extract\configuration.bin .\extract\configuration.bin.decrypted

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

Hex view of the decrypted configuration file

Чтение конфигурации

Формат файла конфигурации представлен ниже.

Configuration file

Конфигурацию можно прочитать с помощью скрипта labs-releases\tools\icedid\gzip-variant\read_configuration.py.

usage: read_configuration.py [--help] input

positional arguments:
  input       Input file

options:
  -h, --help  show this help message and exit

Мы воспользуемся сценарием read_configuration.py для чтения файла Configuration.bin.decrypted, который мы собрали на предыдущем шаге.

python .\gzip-variant\read_configuration.py .\extract\configuration.bin.decrypted

============================================================
Configuration
============================================================
botnet_id: 0x3B7D6BA4
auth_var: 0x00000038
uri: /news/
domains:
        alishaskainz.com
        villageskaier.com

Эта конфигурация содержит два домена C2:

      • alishaskainz[.]com
      • villageskaier[.]com

В этом примере идентификатор URI, который использует ICEDID, — «/news/».

Пересборка основного двоичного файла для статического анализа

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

Custom PE file format

Если мы хотим проанализировать основной двоичный файл, например, с помощью IDA Pro, нам необходимо пересобрать его в действительный PE. Мы используем скрипт labs-releases\tools\icedid\rebuild_pe.py.

usage: rebuild_pe.py [--help] [-o OFFSET] input output

positional arguments:
  input                 Input file
  output                Output reconstructed PE

options:
  -h, --help            show this help message and exit
  -o OFFSET, --offset OFFSET
                        Offset to real data, skip possible garbage

Однако при попытке использовать rebuild_pe.py в расшифрованном базовом двоичном файле License.dat.decrypted мы получаем следующее сообщение об ошибке:

python .\rebuild_pe.py .\extract\license.dat.decrypted .\extract\core.bin
Traceback (most recent call last):
  File "rebuild_pe.py", line 32, in <module>
    main()
  File "rebuild_pe.py", line 28, in main
    custom_pe.CustomPE(data).to_pe().write(args.output)
  File "nightmare\malware\icedid\custom_pe.py", line 86, in __init__
    raise RuntimeError("Failed to parse custom pe")
RuntimeError: Failed to parse custom pe

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

Prepended garbage bytes

Из наших исследований мы знаем, что размер мусора составляет 129 байт.

Identifying garbage size

Имея это в виду, мы можем пропустить байты мусора и пересобрать основной двоичный файл с помощью сценария rebuild_pe.py с параметром «-o 129». На этот раз мы, к счастью, не получили сообщения об ошибке. core.bin будет сохранен в выходной каталог, в нашем примере это извлеченный файл.

python .\rebuild_pe.py .\extract\license.dat.decrypted .\extract\core.bin -o 129

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

IDA view of core.bin

Мы присвоили собственные имена перестроенным двоичным разделам ( .mare{0,1,2,…} ).

Rebuilt binary section names

Мы хотим отметить и поблагодарить работу Хашерезаде, которая вдохновила нас на создание этого инструмента.

Выполнение основного двоичного файла (только для Windows)

Основной двоичный файл не может быть выполнен без специального загрузчика, который понимает специальный формат PE ICEDID, а также прототип функции точки входа.

Из наших исследований мы знаем, что точка входа ожидает структуру, которую мы называем структурой контекста, которая содержит ядро ​​ICEDID и пути постоянного загрузчика с зашифрованной конфигурацией. Структура контекста описана ниже.

Context structure

Для запуска основного двоичного файла мы используем сценарий labs-releases\tools\icedid\gzip-variant\load_core.py, но перед его использованием нам необходимо создать файл context.json, который будет содержать всю информацию, необходимую для этого сценария. построить эту структуру.

В этом примере мы копируем информацию, содержащуюся в поддельном gzip, и используем путь к зашифрованному файлу конфигурации. Мы включили пример в gzip_variant/context.json.example.

Example configuration file

Обратите внимание, что значения «field_0» и «stage_2_export» необходимо найти при реверсировании выборки.

Populating values from previous research

Здесь мы используем значения из нашего предыдущего исследования в качестве заполнителей, но у нас нет гарантии, что образец будет работать на 100%. Например, в этом примере мы не знаем, является ли порядковый номер экспорта №1 фактической точкой входа в загрузчик сохраняемости.

Мы также воспроизводим поведение первого этапа, создав каталог UponBetter и переместив в него файл License.dat.

license.dat in the UponBetter directory

Мы выполняем сценарий labs-releases\tools\icedid\gzip_variant\load_core.py, используя расшифрованный двоичный файл ядра: License.dat.decrypted, файл context.

ВНИМАНИЕ: двоичный файл будет загружаться/выполняться с помощью этого сценария. Elastic Security Labs не несет ответственности за любой ущерб вашей системе. Пожалуйста, выполняйте только в безопасной среде.

usage: load_core.py [--help] [-o OFFSET] core_path ctx_path

positional arguments:
  core_path             Core custom PE
  ctx_path              Path to json file defining core's context

options:
  -h, --help            show this help message and exit
  -o OFFSET, --offset OFFSET
                        Offset to real data, skip possible garbage

Поскольку у нас та же проблема с байтами мусора, что и в предыдущем разделе, мы используем параметр «-o 129», чтобы пропускать байты мусора.

python .\gzip-variant\load_core.py .\extract\license.dat.decrypted .\gzip-variant\context.example.json -o 129

============================================================
Core Loader
============================================================
Base address: 0x180000000
Entrypoint: 0x180001390

Press a key to call entrypoint...

При запуске скрипт будет ждать ввода пользователя перед вызовом точки входа. Мы можем легко подключить отладчик к процессу Python и установить точку останова на точке входа ядра ICEDID .

Breakpoint set on the ICEDID core entry point

Как только клавиша нажата, мы достигаем точки входа.

ICEDID entry point

Если мы позволим бинарному файлу выполниться, мы увидим создание потоков ICEDID (показано на следующем снимке экрана).

ICEDID threads being created

Распаковка и восстановление полезных данных из восстановленного основного двоичного файла.

Для извлечения любых полезных данных, встроенных в основной двоичный файл, мы будем использовать скрипт labs-releases\tools\icedid\gzip-variant\extract_payloads_from_core.py.

usage: extract_payloads_from_core.py [--help] input output

positional arguments:
  input       Input file
  output      Output directory

options:
  -h, --help  show this help message and exit

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

python .\gzip-variant\extract_payloads_from_core.py .\extract\core.bin core_extract

core_extract\browser_hook_payload_0.cpe
core_extract\browser_hook_payload_1.cpe

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

ICEDID payloads

Основываясь на наших исследованиях, мы знаем, что браузер_hook_payload_0.cpe — это версия x64 полезной нагрузки браузерного перехватчика, а браузер_hook_payload_1.cpe — это версия x86.

Browser hook payload architectures

Чтобы их пересобрать, мы снова используем скрипт rebuild_pe.py, на этот раз в нем нет мусорных байтов, которые можно было бы пропустить.

python .\rebuild_pe.py .\core_extract\browser_hook_payload_0.cpe .\core_extract\browser_hook_payload_0.bin

python .\rebuild_pe.py .\core_extract\browser_hook_payload_1.cpe .\core_extract\browser_hook_payload_1.bin

Теперь у нас есть два двоичных файла PE (браузер_hook_payload_0.bin и браузер_hook_payload_1.bin), которые мы можем проанализировать.

Payloads for further analysis

Заключение

В этом руководстве мы рассмотрели распаковку варианта ICEDID GZip, начиная с извлечения поддельного двоичного файла GZip, за которым следует реконструкция основного двоичного файла и распаковка его полезных данных.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Click to rate this post!
[Total: 0 Average: 0]

Leave a reply:

Your email address will not be published.