Это испытание с MetaCTF CyberGames 2021, в рамках которого нужно было выполнить криминалистическую экспертизу дампа памяти .NET. Проведение такой экспертизы может быть многим незнакомо, так что, надеюсь, данная статься окажется полезной.
Вход в NET
В качестве торжественного финала пришло время объединить все ваши навыки криминалистической экспертизы. Вам предстоит немного поработать с Криптографией и Реверс-инжинирингом, а также с большим объемом Анализа.
В этой задаче сбор перехваченных пакетов и дампа процесса предлагаемого вам для рассмотрения маячка мы взяли на себя.
С целью предоставления нашему руководству необходимой ясности, мы хотим знать конкретно, какие действия атакующие предпринимали на этой особо ценной машине (имейте ввиду – здесь дамп/перехваченные пакеты отличаются от всех предыдущих задач). Поэтому, чтобы воссоздать картину произошедшего, вам потребуется сопоставить информацию в перехваченных пакетах и извлечь необходимые критические данные из дампа памяти.
Решение
Анализ пакетов
Для начала рассмотрим перехват пакетов с помощью wireshark, чтобы понять, с чем мы имеем дело.
Здесь я сходу замечаю два интересующих нас пакета:
GET /en-us/docs.html
вызывает интерес, потому что сразу же следом мы наблюдаем отправку большого объема данных. При этом я не придаю значения GET /latest/meta-data/instance-action
, так как это что-то о сервере EC2 AWS, который по случайности был оставлен. Чтобы увидеть, как рассматриваемые пакеты задействованы во всем сеансе, используем
follow http stream
.Сразу же выделяется одна деталь: весь сеанс составляет 630Кб. Похоже, что здесь была передана программа. Я постарался найти среди огромных блоков текста какие-нибудь полезные данные, но они, скорее всего, зашифрованы.
Здесь немного полезной информации, просто перехваченные пакеты, показывающие скачивание чего-то зашифрованного.
Анализ дампа
Это файла дампа Windows, поэтому мы его проанализируем с помощью
WinDbg
.Для анализа программы .NET сначала нужно установить netext.
0:000> .load netext
Дамп кода
Сначала нам необходимо проверить выполняющийся код. Для этого потребуется сделать его дамп.
0:000> !wmodule -managed -saveto C:\Users\IEUser\Downloads\net\dump
Saved 'C:\Users\IEUser\Downloads\net\dump\Grunt.exe' successfully
Saved 'C:\Users\IEUser\Downloads\net\dump\System.Windows.Forms.ni.dll' successfully
Saved 'C:\Users\IEUser\Downloads\net\dump\System.Drawing.ni.dll' successfully
Saved 'C:\Users\IEUser\Downloads\net\dump\System.Xml.ni.dll' successfully
Saved 'C:\Users\IEUser\Downloads\net\dump\System.Configuration.ni.dll' successfully
Saved 'C:\Users\IEUser\Downloads\net\dump\System.Core.ni.dll' successfully
Saved 'C:\Users\IEUser\Downloads\net\dump\System.ni.dll' successfully
Saved 'C:\Users\IEUser\Downloads\net\dump\mscorlib.ni.dll' successfully
Saved 'C:\Users\IEUser\Downloads\net\dump\ta2521lw.nbq, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' successfully
Saved 'C:\Users\IEUser\Downloads\net\dump\if3vizgz.gue, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' successfully
Saved 'C:\Users\IEUser\Downloads\net\dump\EILxxsbDHTbdXhkqQNppeCxDtWdOB, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' successfully
Saved 'C:\Users\IEUser\Downloads\net\dump\q2foozwn.pi1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' successfully
Saved 'C:\Users\IEUser\Downloads\net\dump\OUZWwjnRdRpuqIqXtbtAdEDpAmRDA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' successfully
Как всегда при работе с программами .NET скачиваем не системные файлы в
dnSpy
.EILxxsbDHTbdXhkqQNppeCxDtWdOB.dll
Это просто пустая dll.
kxwieowc.bru.exe
У этого исполняемого файла есть точка входа в
GruntStager.GruntStager.Main
. Через Google выясняем, что это, скорее всего, Covenant Grunt – развертываемый на целях имплант.Похоже, что он проделывает немало работы для скачивания сборки и ее загрузки с помощью
Assembly.Load(aes2.CreateDecryptor()...
.if3vizgz.gue.dll
Здесь находится библиотека SharpSploit, используемая для выполнения кода Powershell.
OUZWwjnRdRpuqIqXtbtAdEDpAmRDA.dll
Просто пустая dll.
q2foozwn.pi1.dll
А вот эта dll содержит интересный атрибут:
[module: ConfusedBy("Confuser.Core 1.1.0-alpha1.52+gfe12a44191")]
Получается, этот исполняемый файл защищен ConfuserEx, поддержка которого была прекращена. Раз он под защитой, то добраться до него можно через дамп памяти.
public static class Task
{
// Token: 0x06000035 RID: 53 RVA: 0x000033CC File Offset: 0x000015CC
public static string Execute()
{
string result;
try
{
int left = SystemInformation.VirtualScreen.Left;
int top = SystemInformation.VirtualScreen.Top;
int width = SystemInformation.VirtualScreen.Width;
int height = SystemInformation.VirtualScreen.Height;
using (Bitmap bitmap = new Bitmap(width, height))
{
using (Graphics graphics = Graphics.FromImage(bitmap))
{
graphics.CopyFromScreen(left, top, 0, 0, bitmap.Size);
}
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Png);
result = Convert.ToBase64String(memoryStream.ToArray());
Не удивительно, что эта часть была защищена. Похоже, здесь у нас задача для Grunt – сделать скриншот и вернуть его. Посмотрим, удастся ли найти этот скриншот в
dmp
.ta2521lw.nbq.dll
Это основной
GruntExecutor
, который только взаимодействует с другими Grunt'ами, сам при этом ничего интересного не делая.Анализ памяти
Часть 1/2
Мы знаем, что флаги представлены, как минимум, в формате
*_*_*
. Почему бы тогда не проверить, не находится ли он уже в памяти.Для начала выполним:
0:000> !windex
В результате netext сможет проиндексировать все объекты в памяти, готовые для наших запросов, после чего можно будет начать поиск возможного флага.
0:000> !wfrom -type System.String where ( $wildcardmatch($string(), "*_*_*") ) select $addr(), $string()
...
calculated: cmd.exe /c echo "part 1/2: when_you_see_sharp_"
Здесь было много ложных результатов, но я думаю, что это его первая часть.
Часть 2/2
До этого мы видели задачу по снятию скриншота, который, готов поспорить, и был флагом. Вопрос лишь в том, как получить изображение?
Оно находится в
System.Drawing.Bitmap
, значит стоит поискать его в памяти.0:000> !windex -type System.Drawing.Bitmap
Index is up to date
If you believe it is not, use !windex -flush to force reindex
Address MT Size Heap Gen Type Name
0000000002620fd8 00007ffd6140bed8 48 0 0 System.Drawing.Bitmap
1 Objects listed
Мы видим, что в памяти находится всего один точечный рисунок, который, скорее всего, и является искомым скриншотом.
0:000> !wdo 0000000002620fd8
Address: 0000000002620fd8
Method Table/Token: 00007ffd6140bed8/200000e04
Class Name: System.Drawing.Bitmap
Size : 48
EEClass: 00007ffd61412fd0
Instance Fields: 4
Static Fields: 1
Total Fields: 5
Heap/Generation: 0/0
Module: 00007ffd61400000
Assembly: 0000000000a0d3a0
Domain: 0000000000947110
Assembly Name: C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll
Inherits: System.Drawing.Image System.MarshalByRefObject System.Object (00007FFD6140B798 00007FFD6AC3AB68 00007FFD6AC35DD8)
00007ffd6ac35dd8 System.Object +0000 __identity 0000000000000000
00007ffd6ac3aaa0 System.Byte[] +0008 rawData 0000000000000000
00007ffd6ac35dd8 System.Object +0010 userData 0000000000000000
00007ffd6acb31f8 System.IntPtr +0018 nativeImage 0 (0n0)
00007ffd6140ac20 Static System.Drawing.Color +0050 defaultTransparentColor -mt 00007FFD6140AC20 000000001243B188
Тем не менее, если посмотреть дамп этого изображения, то нам не удастся найти способ получить фактические данные.
Попробуем отыскать этот рисунок в памяти с помощью классического инструмента,
binwalk
. $ binwalk --dd='.*' step_into_the_net.dmp
Здесь у нас несколько изображений, покопавшись в которых я нашел
83AABA
, который содержит вторую часть флага.Решено
Совмещая эти две строки, получаем решение:
when_you_see_sharp_those_hackers_dont_stand_a_chance
Когда ты наблюдателен, у хакеров не остается шансов
Заключение
Это был весьма интересный вызов по криминалистической экспертизе. Дамп Windows мне еще анализировать не доводилось, так что пришлось знакомиться с несколькими новыми инструментами. Большое спасибо MetaCTF за предоставление такого испытания.