Занимательная форензика. Извлекаем пароль из дампа памяти с помощью Volatility и GIMP
Задачи на форензику (криминалистику) в соревнованиях Capture The Flag делятся на несколько больших типов: анализ оперативной памяти, жесткого диска и исследование дампов трафика. В этой статье мы разберем задачу Remote Password Manager на тему анализа памяти из соревнования JustCTF 2021, а заодно рассмотрим малоизвестную, но очень полезную фишку GIMP.
ЧТО ДЕЛАЕМ?
Анализ оперативной памяти часто используется, когда у нас был физический доступ к машине и получилось снять слепок оперативной памяти. По нему можно определить, какие приложения запускались во время этого сеанса, потому что, пока человек не выключил или не перезагрузил компьютер, в оперативной памяти хранится интересующая нас информация (например, данные процессов).
INFO
Еще интересные данные можно найти в файлах подкачки (pagefile.sys
) и гибернации (hiberfil.sys
). Для *nix-based-систем стоит поискать в swap-разделе.
Для анализа дампов памяти существует несколько приложений, которые на слуху у всех, кто хоть раз имел дело с задачами на форензику: это Volatility, Memoryze и Autopsy (в связке с Volatility). Есть, конечно, и другие, но подробно мы на них останавливаться не будем.
Крупные решения вроде Autopsy хороши тем, что позволяют произвести комплексный анализ всего слепка одной кнопкой, однако цена за это — большое время работы программы. На соревнованиях обычно необходимо делать задачу максимально быстро, поэтому использовать мы будем Volatility.
ЗАДАНИЕ
Вот как выглядело условие задачи. Нам дан непосредственно слепок оперативной памяти и его хеш MD5 для проверки.
Приблизительный перевод:
У меня есть самый безопасный менеджер паролей. Даже если ты украдешь мой ноутбук, ты не сможешь узнать мои секреты.
Подсказка: Удаленный не значит обязательно браузер
Закачаем наш образ на машину, где будем проводить анализ (у меня это Kali):
$ wget https://ams3.digitaloceanspaces.com/justctf/69f7647d-2f7a-4604-b9f6-553c6bb447ee/challenge.tar.gz
Распакуем:
$ tar -xzvf challenge.tar.gz
И сразу же проверим, что с ним все в порядке:
$ md5sum pub/challenge.vmem
Если хеш не сошелся с исходным хешем — придется еще раз скачать архив.
О важности актуальных версий
Ни для кого не секрет, что с каждым обновлением любого инструмента разработчики стараются добавить новые возможности и убрать старые недокументированные возможности баги. В операционных системах семейства Linux есть встроенные менеджеры пакетов, которые существенно упрощают установку и обновление программ. Из‑за этого большинство людей первым делом лезет в свой пакетный менеджер, чтобы установить оттуда программу.
Однако здесь есть небольшие шероховатости: разработчик может забыть (или забить?) обновить пакет в репозитории. В таких случаях приходится искать исходники и собирать актуальную версию самостоятельно.
Те, кто знаком с Volatility, знают о его особенностях. Например, что он использует так называемые профили, которые позволяют правильно распарсить весь слепок оперативной памяти, и энтузиасты постоянно обновляют их список. Разумеется, профиль можно сделать и самостоятельно, но явно проще воспользоваться готовыми. Во время соревнования я столкнулся с тем, что давно не обновлял свой Volatility и нужных профилей для решения задачи у меня не оказалось.
Чтобы с тобой не случилось подобного, перед началом решения задачи я настоятельно рекомендую обновить (или установить) Volatility с гитхаба проекта.
ОПРЕДЕЛЯЕМ ПРОФИЛЬ
Первым делом нам необходимо определить версию операционной системы, с которой снимали слепок. Это можно сделать командой imageinfo
:
$ vol.py -f challenge.vmem imageinfo
Нам нужно обратить внимание на строчку с Suggested Profile(s). Именно здесь нам говорят, что предполагаемый профиль слепка оперативной памяти — Win10x64_18362
. Теперь мы должны указывать аргумент --profile Win10x64_18362
для последующих команд.
WWW
Полная документация по Volatility есть в Wiki по инструменту на GitHub.
СОБИРАЕМ ИНФОРМАЦИЮ О МАШИНЕ
Какую информацию имеет смысл добыть вначале? Обычно это:
- процессы;
- история браузера;
- история запущенных команд в консоли.
Этих трех пунктов хватает для определения вектора дальнейшей разведки.
Процессы
Чтобы найти процессы, нам достаточно использовать команду pstree
. Есть еще pslist
, но первая команда удобнее, потому что показывает процессы в виде дерева — так намного проще понять, на какие из них стоит обратить внимание.
$ vol.py -f challenge.vmem --profile Win10x64_18362 pstree
Ничего бросающегося в глаза, вроде pswd_manager.exe
или not_a_virus.exe
, не видно, поэтому продолжим нашу разведку.
История браузера
Хоть в хинте и говорилось, что «удаленный» не обязательно значит «браузер», мы проверим этот вектор. В Volatility есть готовый плагин для просмотра истории Internet Explorer — iehistory
. И не говори, что им уже никто не пользуется!
$ vol.py -f challenge.vmem --profile Win10x64_18362 iehistory
Команда работала слишком долго на моей машине (порядка 20 минут) и завершаться не планировала. Это не считается нормальным поведением для Volatility, следовательно, тут искать нечего.
INFO
Если ты подумаешь составлять задачки для CTF — имей в виду, что задачи, в которых надо по полчаса брутить извращенные пароли или искать неуловимый API endpoint, никто не любит, и следующую задачу тебе доверят делать еще не скоро.
Список команд в консоли
Есть еще одна удобная функция для проверки всех введенных в консоль команд. Возможно, пользователь запускал что‑нибудь из консоли или хранил там важные данные (например, флаг). Проверить все из консоли можно с помощью команды cmdscan
.
$ vol.py -f challenge.vmem --profile Win10x6_18362 cmdscan
Тут чисто — следовательно, терминал тоже не при делах.
Что еще можно сделать?
Поскольку до сих пор не нашлось ничего интересного — мы что‑то упустили. Можно применить еще один полезный прием при анализе оперативной памяти — посмотреть на скриншот рабочего стола. Помогает он не сильно часто, но позволяет увидеть более полную картину.
Сделать скриншот всех окон процессов в системе можно при помощи команды screenshot
. Обязательно нужно указать существующую конечную директорию, где будут находиться все снимки. Важно понимать, что большинство картинок будут пустыми: это связано с тем, что не все окна вообще могут отображаться (для лучшего понимания рекомендую ознакомиться с документацией).
$ vol.py -f challenge.vmem --profile Win10x64_18362 screenshot -D shot/
К сожалению, команда заканчивается с ошибкой, так что этот трюк тоже не прошел и нам стоит вернуться к самому началу.
ПЕРЕПРОВЕРЯЕМ ИНФОРМАЦИЮ
В названии задачи фигурирует слово remote (удаленный) — давай попробуем найти что‑то, что может взаимодействовать с сетью.
Попробуем снова проверить все процессы, которые у нас фигурируют в этом слепке оперативной памяти. Заметим среди них mstsc.exe
— Microsoft Terminal Services Client, или, в простонародье, RDP-клиент. RDP — это проприетарный протокол для доступа к удаленным рабочим столам. Для нас важно то, что протокол предусматривает передачу картинки по кадрам в виде сжатых битмапов, которые разжимаются и отображаются, а в это время хранятся в памяти.
Возможно, в этом процессе мы сможем найти флаг. Найдем его PID, чтобы мы могли сдампить память процесса:
$ vol.py -f challenge.vmem --profile Win10x64_18362 pslist | grep mstsc.exe
Номер процесса — 6484
.
ДАМПИМ ПАМЯТЬ
У каждого процесса есть своя выделенная память, которая хранится как раз в оперативке (внезапно, не так ли?). Попробуем сдампить ее, чтобы найти полезную информацию из этого процесса.
$ vol.py -f challenge.vmem --profile Win10x64_18362 memdump -p 6484 -D data
Хранение картинок в памяти
Напоминаю, что mstsc.exe
(да и другие RDP-клиенты тоже) получают картинку, которую хранят у себя где‑то в оперативной памяти. Благодаря этой особенности мы можем попробовать извлечь картинку из этого дампа процесса. Возникнет только одна небольшая проблема: правильно подобрать смещение, так как картинка в памяти процесса хранится в сыром виде, и ни binwalk
, ни foremost
не могут ее отыскать, чтобы сохранить как отдельный файл.
INFO
Такой трюк можно применять не только для процесса mstsc.exe
, но и на процессы вроде mspaint.exe
, virtualbox.exe
и другие, которые работают примерно по такому же принципу.
Для подбора смещения расчехляем графический редактор GIMP. Как прочитать картинку, если она начинается не в начале файла? Да запросто!
Нужно открыть дамп процесса как Raw Image Data, то есть как сырую картинку, иначе мы не сможем подбирать смещение.
Дальше появляется окошко, где мы можем выбирать смещение.
И начинаем его прокручивать. Для удобства я увеличил свое окошко по ширине, чтобы было легче управлять ползунком. Во время перемещения я заметил следующую картинку, которая похожа на кусок рабочего стола Windows, что наводит на мысль о близости к флагу.
А вот и флаг!
КРАТКИЕ ВЫВОДЫ
Перед решением любых задач не забывай обновлять используемые утилиты! Не обновив утилиту или неправильно прочитав документацию к ней, можно попасть в rabbit hole и не сдать задачу вовремя. А как мы знаем, не бывает поздно, бывает уже не надо.