Уроки форензики. Исследуем вредоносные документы Microsoft Office

Marat_1162

Стаж на ФС с 2014 г
Private Club
Старожил
Migalki Club
Меценат
Регистрация
25/3/16
Сообщения
4.639
Репутация
9.166
Реакции
22.683
RUB
0
Депозит
3 500 рублей
Сделок через гаранта
4
Один из самых распространенных векторов атак на организации и простых пользователей — социальная инженерия. Злодеи присылают жертве электронное письмо с вложением, очень часто — документ Microsoft Office с опасным содержимым. В этой статье мы разберемся, как анализировать такие документы и как искать в их недрах вредоносный код.

Согласно матрице MITRE ATT&CK, атака, в которой злоумышленники используют документы Microsoft Office, называется Spearphising Attachment. Чтобы рассказать о методах анализа применяемых в таких атаках файлов, я воспользуюсь двумя заданиями с ресурса CyberDefenders. Первое из них — Obfuscated — позволит нам исследовать вредоносный документ в формате DOC. С помощью второго, под названием Emprisa Maldoc, мы разберем, как злоумышленники используют документ RTF для выполнения шелл‑кода.

Существуют следующие методы выполнения вредоносного кода в документах Microsoft Office.

  1. Выполнение кода, встроенного в макрос VBA.
  2. Выполнение JavaScript в документах Microsoft Office.
  3. Выполнение полезной нагрузки с использованием уязвимостей в приложениях Microsoft Office.
Для нашей работы мы будем использовать следующий набор утилит:

  • oleid — для анализа OLE-файлов;
  • olevba — для извлечения и анализа исходного кода макросов VBA из документов MS Office (OLE и OpenXML);
  • oledump — для анализа потоков данных OLE-файла;
  • rtfdump — для анализа файлов формата RTF;
  • rtfobj — для извлечения встроенных объектов из файлов RTF;
  • scdbg — для анализа шелл‑кода, утилита построена на основе библиотеки для эмуляции libemu.

INFO​

Все необходимые для анализа вредоносных документов утилиты находятся в каталоге FLARE\Office виртуальной машины под управлением Windows 10.

Итак, приступим к изучению файлов с сайта CyberDefenders. Я не буду приводить ответы на вопросы из заданий — повторив все описанные ниже эксперименты, ты сможешь найти их сам.

OBFUSCATED​

Загрузим с сайта архив с заданием. Первым делом посчитаем хеш MD5 содержащегося в архиве файла (в результате получится значение 49b367ac261a722a7c2bbbc328c32545) и проверим его на VirusTotal.

Теперь получим информацию о структуре вредоносного документа. Для этого воспользуемся утилитой oleid.

oleid 49b367ac261a722a7c2bbbc328c32545

sgigJqFmWoY.jpg

Информация об объекте исследования

Тулза определила, что это документ Microsoft Office Word и в нем есть VBA-макрос. Его нам предстоит вытащить наружу. Для начала воспользуемся утилитой oledump и посмотрим, в каком потоке содержится VBA-макрос.

oledump 49b367ac261a722a7c2bbbc328c32545

1fNAzBZKBxA.jpg

Потоки исследуемого документа

Макрос спрятался в восьмом потоке данных. Выгрузим его при помощи инструмента olevba с ключом -a.

olevba -a 49b367ac261a722a7c2bbbc328c32545

rdbGPfAKRNM.jpg

Результат работы утилиты olevba

В потоке Macros/VBA/Module1 сосредоточена основная функциональность вредоносного скрипта. Из вывода утилиты видно, какие функции он использует. Давай извлечем этот скрипт и начнем исследовать код.

olevba -c 49b367ac261a722a7c2bbbc328c32545

ESev8CNAAUo.jpg

Участок обфусцированного кода вредоносного VBA-макроса

Функция AutoOpen() запускает выполнение скрипта, когда документ открывают. Чтобы усложнить нам работу, злоумышленники обфусцировали код VBA-макроса: имена переменных представлены в формате Base64. Мы будем вручную деобфусцировать код и разберем его функциональность.

INFO​

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

Начнем с функции AutoOpen().

Kt6iUV24WoU.jpg

Участок кода функции AutoOpen

На картинке ты видишь выделенный фрагмент кода, содержащий несколько очень интересных функций. Функция FileLen(ActiveDocument.FullName) получает размер документа Word и записывает его в переменную N18Eoi6OG6T2rNoVl41W. Функция Open(ActiveDocument.FullName) открывает документ в бинарном формате, затем записывает его содержимое в переменную E2kvpmR17SI и преобразует считанные строки в кодировку Unicode.

Во втором выделенном блоке с использованием объекта vbscript.regexp выполняется поиск такой строки в открытом файле:

MxOH8pcrlepD3SRfF5ffVTy86Xe41L2qLnqTd5d5R7Iq87mWGES55fswgG84hIRdX74dlb1SiFOkR1Hh

В переменной Y5t4Ul7o385qK4YDhr хранится указатель на первый символ найденной строки в исходном документе.

f19C8Wu4pMY.jpg

Продолжение участка кода функции AutoOpen

Обфусцированный вредоносный код расположен после обнаруженной нами строки, его размер составляет 16 827 байт.

woy6xFljfC0.jpg

Начало полезной нагрузки

Из файла считывается информация начиная с байта 0x503c, далее декодируется по алгоритму, который мы разберем ниже, и сохраняется в файл %appdata%\Microsoft\Windows\maintools.js. Затем с помощью WScript.Shell выполняется JS-скрипт maintools.js с параметром EzZETcSXyKAdF_e5I2i1.

Давай разберем алгоритм декодирования и напишем небольшую программу на Python для получения исходного JS-скрипта.

fJBt3iQ3jb4.jpg

Функция декодирования полезной нагрузки

Для удобства чтения кода я переименовал переменные. Алгоритм декодирования очень прост. С каждым байтом выполняется операция XOR (исключающее «или») с ключом, который хранится в переменной KEY. После каждого преобразования байта изменяется и сам ключ.

Напишем собственный скрипт для декодирования полезной нагрузки, используя Python 3.

import re

def Decode(bVar):

# Алгоритм декодирования полезной нагрузки

result = ""

key = 45

for i in range(0,len(bVar)):

result += chr(bVar ^ key)

key = (key ^ 99) ^ (i % 254)

return result

reg = b"MxOH8pcrlepD3SRfF5ffVTy86Xe41L2qLnqTd5d5R7Iq87mWGES55fswgG84hIRdX74dlb1SiFOkR1Hh"

f = open("49b367ac261a722a7c2bbbc328c32545","rb")

w = open("maintools.js","w") # Файл для записи раскодированной полезной нагрузки

data_read = f.read()

start = re.search(reg,data).span()[1] # Начало полезной нагрузки

stop = start + 16827 # Конец полезной нагрузки

data1 = data_read[start:stop]

w.write(Decode(data))

f.close()

w.close()

Этот скрипт находит строку MxOH8... в исследуемом документе и считывает данные размером 16 827 байт. Далее по алгоритму, реализованному в функции Decode, он расшифровывает полезную нагрузку и сохраняет результат в файл maintools.js.

Итак, с помощью нашей программы мы вытащили расшифрованный JS-сценарий. Посмотрим, что у него внутри?

OgiYYQmjkxw.jpg

Основной код вредоносного скрипта до преобразования переменных

В переменную wvy1 сохраняются аргументы командной строки. Функция y3zb() возвращает основную полезную нагрузку, которая преобразуется по определенному алгоритму. Рассмотрим эту функцию повнимательнее.

Baod1oSVORM.jpg

Участок кода, содержащий полезную нагрузку

В переменной qGxZ хранится основной вредоносный код, который перед выполнением декодируется. Но чтобы понять принцип расшифровки, сначала переименуем название переменных в скрипте — просто ради удобства.

ELTWfBhBL1M.jpg

Основной код после преобразования переменных

В функции LXv5 реализован алгоритм декодирования Base64, поэтому переименуем ее в Base64_decode. Функция CpPT содержит алгоритм шифрования RC4, дадим ей имя RC4(). Этой функции в качестве аргумента передается строка EzZETcSXyKAdF_e5I2i1, которая является аргументом командной строки и одновременно ключом для деобфускации полезной нагрузки. А расшифрованный код JavaScript выполняет функция eval.

-ItrMeG6vYY.jpg

Участок кода, в котором реализован алгоритм шифрования RC4

В первых двух циклах реализован алгоритм Key-scheduling algorithm, с помощью которого в дальнейшем генерируется ключ. Напишем скрипт на Python 3, расшифровывающий полезную нагрузку из переменной qGxZ функции y3zb().

from Crypto.Cipher import ARC4

import base64

payload = "zAubgpaJRj0tIneNNZL0 ... rbhue4N84o9YPBy/SFieRfjQP5lsrSZWJKNJ5ZSbf06ZO4=";

key = b"EzZETcSXyKAdF_e5I2i1"

rc4 = ARC4.new(key)

decode = rc4.decrypt(base64.b64decode(payload))

w = open('result.js','wb')

w.write(decode)

w.close()

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

2AZXSgG7EDI.jpg

Участок полученного JavaScript-кода

Этот сценарий собирает информацию о скомпрометированной системе и отправляет ее на управляющие серверы.

vfJEaaeBVf0.jpg

Заголовок отправляемых данных
Из рисунка выше виден заголовок, который формируется для отправки данных методом POST.

IcKH4uh4ihc.jpg

Метод закрепления в системе

После запуска вредоносный скрипт копирует себя в следующую папку:

C:\Users\<Пользователь>\AppData\Local\Microsoft\Windows

А затем создает в планировщике задач Windows новую задачу, которая запускается при входе пользователя в систему. Задача имеет имя Task Manager, описание Windows Task Manager, а сам скрипт запускается из каталога WPD. Найти в системе это задание можно с помощью команды schtasks /query /fo csv /v, а еще можно просто зайти в папку C:\Windows\System32\Tasks и отыскать в ней подкаталог WPD. Весь свой трафик сценарий шифрует алгоритмом RC4 с ключом 2f532d6baec3d0ec7b1f98aed4774843. Для запуска JS-скрипта используется утилита командной строки cscript.exe.



EMPRISA MALDOC

Разберем задание с вредоносным документом в формате Microsoft Rich Text Format (RTF). Такие файлы очень часто используются злоумышленниками при фишинговых атаках и, как правило, содержат эксплоиты.

Для начала соберем информацию об объекте исследования с помощью утилиты rtfobj.

rtfobj c39-EmprisaMaldoc.rtf

1wUqHdMACuM.jpg

Вывод работы утилиты rtfobj

Тулза определила, что RTF-документ содержит встроенный объект. Для выполнения вредоносного кода используется уязвимость CVE-2017-11882, эксплуатирующая переполнение буфера в редакторе Microsoft Equation. Проанализируем этот файл с помощью утилиты rtfdump.

rtfdump c39-EmprisaMaldoc.rtf

4CuDCDkUaQ0.jpg

Объекты, расположенные в исследуемом файле

Как видно из рисунка, в документе спрятан объект с именем Equation.e, magic-байт d0cf11e0. Исследуем поток 7, затем выгрузим из него OLE-объект и сохраним в файл objrtf.

rtfdump c39-EmprisaMaldoc.rtf -s 7 -H -E -d > objrtf

Полученный OLE-объект можно изучить при помощи утилиты oledump.

oledump objrtf

69S72bXu_5Q.jpg

Анализ OLE-объекта

После строки Equation Native в шестнадцатеричном представлении содержится обфусцированный шелл‑код. Сохраним его дамп в файл shell.

oledump objrtf -s 4 -d > shell

sNk5utPk1O0.jpg

Шестнадцатеричное значение шелл‑кода

Чтобы разобраться, как работает этот шелл‑код, нам понадобится утилита scdbg. Запустим ее с параметром /findsc, который эмулирует выполнение шелл‑кода при каждом смещении в файле.

scdbg /f shell findsc

_XiDli-52no.jpg

Эмуляция вредоносного шелл‑кода

Функция LoadLibraryA загружает динамическую библиотеку urlmon.dll. Далее с использованием функции URLDownloadToFileA из этой библиотеки с ресурса raw.githubusercontent.com скачивается полезная нагрузка и сохраняется в файл o.exe. Затем выполняется выход из процесса с помощью функции ExitProcess.

Получим полезную нагрузку и посмотрим, что это такое. Адрес следующий:



Поведенческий анализ вредоносного документа

Зайдем в виртуальную машину Kali Linux, перейдем в каталог /var/lib/inetsim/http/fakefiles и сохраним полезную нагрузку под именем sample.png.

ck95OD0vRHs.jpg

Полезная нагрузка, сохраненная в файл‑заглушку Inetsim

Вернемся в виртуальную машину с Windows 10, установим Microsoft Office и откроем в нем исследуемый файл c39-EmprisaMaldoc.rtf, чтобы проанализировать его поведение.

Если файл открыть, запустится дочерний процесс EQNEDT32.EXE (компонент MS Office, отвечающий за вставку и редактирование объектов OLE в документы). Уязвимость срабатывает, когда EQNEDT32.EXE пытается скопировать имя шрифта в локально созданный буфер. Размер буфера составляет всего 40 (0x28) байт, однако, если имя шрифта длиннее 40 байт, буфер и регистр EBP переполнятся, а адреса возврата будут перезаписаны. Когда функция завершит выполнение, поток управления доставится по назначенному злоумышленником адресу.

Выполняющийся таким образом шелл‑код загружает полезную нагрузку из виртуальной машины Kali Linux (файл sample.png) и сохраняет по пути C:\o.exe. После запуска этого исполняемого файла появляется модальное окно, содержащее флаг.

RMGnhRt3DsA.jpg

Вывод полезной нагрузки

Давай посмотрим, какое имя шрифта загружается процессом, когда открывают вредоносный документ. Для этого запустим Proccess Hacker 2, откроем документ, найдем процесс Winword.exe и перейдем на вкладку Memory. В памяти отыщем обращение к папке C:\Windows\Fonts и увидим, что процесс пытается загрузить шрифт times.ttf. Значит, это шрифт Times New Roman.



ВЫВОДЫ

На этих двух примерах мы рассмотрели методику исследования подозрительных документов, которые распространяются злоумышленниками по электронной почте при фишинговых атаках. На GitHub можно найти РОС для рассмотренной нами эксплуатации уязвимости CVE-2017-11882, который выполняет шелл‑код по адресу в памяти 0x00402114. Microsoft закрыла эту уязвимость, выпустив патч KB4011604. Не забудь установить это обновление, чтобы обезопасить себя от подобной атаки.

 
Сверху Снизу