May 8, 2021

Занимательная форензика. Извлекаем пароль из дампа памяти с помощью 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 и не сдать задачу вов­ремя. А как мы зна­ем, не быва­ет поз­дно, быва­ет уже не надо.