Skip to content
KitploitKITPLOIT
ИнструментыБлог
Log in
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-25243 — Стабильный POC для CVE-2026-25243 (Redis RESTORE double-free -> удалённое выполнение кода) | Kitploit
Инструменты/GitHubGitHub/captain-woof/cve-2026-25243
Анализ уязвимостейЭксплуатацияПост-эксплуатацияТестирование на ПроникновениеRed TeamingБезопасность Баз ДанныхЭксплуатация Бинарных Файлов
GitHubcaptain-woof/cve-2026-25243

CVE-2026-25243

Стабильный POC для CVE-2026-25243 (Redis RESTORE double-free -> удалённое выполнение кода)

Репозиторий
1131 месяц назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-25243 — Redis RESTORE double-free → удалённое выполнение кода

Проверено на Rocky Linux 8.10, aarch64, Redis 8.6.2, jemalloc 5.3.0.

Ссылка: https://www.zeroday.cloud/blog/redis-cve-2026-25243-deep-dive

TLDR; Стабильный эксплойт, работает на различных дистрибутивах ОС и архитектурах.


Краткое резюме

Что это? Уязвимость повреждения памяти в Redis, которая позволяет аутентифицированному атакующему выполнять произвольные команды от имени пользователя Redis. Атака реальна и требует лишь одной команды RESTORE — обычной операции Redis, а не только для администратора. Этот эксплойт демонстрирует полный RCE менее чем за секунду.

Влияние? Любой аутентифицированный клиент Redis может её вызвать, и ущерб тотален: произвольное выполнение кода в процессе Redis (часто работающем от root в контейнерах). Без патча самого Redis смягчить это невозможно.

Как это работает в двух словах? У Redis есть функция сериализации (RESTORE), которая принимает блоб двоичных данных и восстанавливает его как объект Redis. Код, проверяющий формат блоба, и код, десериализующий его, расходятся в том, как разбирать определённые последовательности, — ошибка, которую атакующий использует для повреждения кучи. После повреждения кучи атакующий получает возможность читать и записывать любой адрес памяти в процессе Redis, а оттуда перехватывает внутреннее состояние сервера, чтобы выполнить команду оболочки.

Реальная техника эксплойта: Это не простой краш. Это цепочка heap-эксплойта: corrupt → overlap → произвольное чтение/запись → утечка информации → поиск структуры server → перехват указателей на функции → RCE. Эксплойт проходит 9 стадий и требует утечки множества адресов в рантайме, разбора двоичных структур и обнаружения алиасинга памяти. То, что заставляет его работать на разных архитектурах (x86-64, aarch64 и т. д.), — все адреса утекают из самой цели, а не предполагаются.


1. Уязвимость — подробно

CVE-2026-25243 — это пара double-free ошибок, достижимых одной аутентифицированной командой RESTORE. RESTORE key ttl <serialized-value> десериализует управляемый атакующим RDB-блоб; обе ошибки находятся в разрыве между валидатором, проверяющим блоб, и конвертером, который материализует его.

Ошибка 1 — преобразование устаревшего zipmap (CWE-415, путь, который использует этот эксплойт). Валидатор zipmap (zipmapValidateIntegrity()) и конвертер (zipmapNext()) расходятся во мнении об избыточной кодировке длины. Маленькая длина 4 может быть легально записана в длинной пятибайтовой форме FE 04 00 00 00. Валидатор потребляет одно количество байт, конвертер — другое: рассинхронизация парсинга на 4 байта. Поэтому конвертер обходит иную структуру, не ту, что была проверена; lpSafeToAdd() завершается ошибкой уже после того, как поле вставлено в словарь, и путь очистки освобождает поле дважды: один раз через dictRelease() и ещё раз через sdsfree().

Ошибка 2 — загрузка PEL consumer'а потока (CWE-415). В rdbLoadStreamConsumersGroup() PEL consumer'а, содержащий повторяющийся ID записи, приводит к сбою второго raxTryInsert(), который вызывает streamFreeNACK() для streamNACK, всё ещё принадлежащего глобальному PEL группы. Освобождается дважды. (Выбирается с помощью --vuln-type stream.)

Любая из ошибок даёт атакующему чанк памяти, который одновременно свободен и на который есть ссылка, — классическая отправная точка для heap-overlap эксплойта.

Воздействие: аутентифицированный клиент Redis (без прав администратора, RESTORE — обычная команда работы с данными) получает произвольное выполнение кода от имени пользователя redis — root в образе контейнера по умолчанию.

2. Как работает эксплойт

Девять стадий, каждая из которых превращает более слабый примитив в более сильный:

СтадияПолученный примитивМеханизм
0профиль целиINFO server / INFO memory → версия, архитектура, дистрибутив, pid, путь к исполняемому файлу, время запуска, аллокатор
1double freeнекорректный zipmap (или stream) RESTORE
2два ключа, разделяющие памятьраспылить маркерные ключи на освобождённый чанк, обнаружить алиасинг, затем перезаписать SDS-заголовок одного ключа через его двойника, чтобы раздуть его до 1 МБ «memview»
3произвольное чтение/записьнайти объект INCRBYFLOAT внутри memview, перехватить его поле ptr: GETRANGE/SETRANGE по этому ключу теперь читают/записывают любой адрес
4указатель на образсканировать кучу назад в поисках значения внутри образа redis-server
5&serverспуститься к ELF-заголовку, разобрать program headers, слить сегмент, доступный на запись, сопоставить server.pid
6пейлоад в памятизаписать "/bin/sh", "-c", "<cmd>" и массив argv в memview
7перехваченная структураперезаписать server.executable, server.exec_argv и server.enable_debug_cmd
8RCEDEBUG CRASH-AND-RECOVER → restartServer() → execve(server.executable, server.exec_argv, environ)

Как запустить

python3 exploit.py --host 127.0.0.1 --port 6379 \
    --password mypassword --cmd 'id > /tmp/pwned123.txt'

Проверка:

cat /tmp/pwned123.txt
# uid=0(root) gid=0(root) groups=0(root)

3. Журнал изменений

2026-08-06 — переработка переносимости, надёжности и скорости

Отправная точка: эксплойт работал только на x86-64 и погибал на стадии 3 на цели aarch64. Конечное состояние: полный RCE на aarch64 Rocky Linux 8.10 менее чем за секунду, 116 команд Redis.

a) Снятие цифрового отпечатка цели в рантайме (новое, стадия 0). О цели больше ничего не предполагается. INFO server + INFO memory дают версию Redis, архитектуру CPU (из строки os:), семейство дистрибутива (выводится из gcc_version), аллокатор и — самое важное — три якоря валидации: process_id, executable и точный stat_starttime (server_time_usec/1e6 - uptime_in_seconds). Последующие стадии сверяются с ними вместо догадок.

b) Независимая от архитектуры компоновка памяти. Четыре захардкоженных константы x86-64 (BINARY_ADDR_MIN/MAX, HEAP_ADDR_MIN/MAX) заменены таблицей по архитектурам (ARCH_PROFILES), покрывающей x86_64, aarch64 (VA и 39-, и 48-бит), riscv64, ppc64le и s390x, с размещениями как ET_EXEC, так и ET_DYN для каждой, плюс широкий универсальный запасной вариант для всего остального. Это и была настоящая причина, по которой эксплойт падал на этой цели: утёкший указатель 0x0000ffff8a5fdf32 — вполне себе валидный aarch64 mmap-адрес, который проверка диапазонов x86-64 отвергала.

c) Валидация утечки на основе консенсуса (стадия 3). Вместо доверия захардкоженному окну кучи сканирование теперь собирает каждый структурно валидный объект 1337.NNNNNN в memview и требует, чтобы по крайней мере два из них давали один и тот же базовый адрес memview (ptr - offset_of_value). На практике совпадают 502 кандидата — это доказательство, которого не может дать ни одна таблица диапазонов. Подтверждённый указатель затем калибрует окно кучи в рантайме. Проверка формата также перенесена перед дорогим по round-trip тестом контроля записи.

d) Граница сканирования на стадии 3 (исправление ошибки). Сканирование уходило до захардкоженных 10 МБ, тогда как memview — 1 МБ, поэтому оно читало за конец, получало пустой ответ и падало с AssertionError: Empty data from memview. Теперь оно ограничено реальным STRLEN memview, читает 256 КБ за round-trip вместо 64 КБ, а бессмысленный цикл повторов со сном 6×1 с убран.

e) Стадия 5 переписана: по ELF-ориентирам, без падений (главное). Старая реализация сканировала вперёд от указателя на образ, опрашивая адреса и читая ту длину, которую заявлял мусорный SDS-заголовок. На этой цели она ушла прямо за конец сегмента только для чтения в незамапленную дыру на 0x715000 и убила сервер (SIGSEGV в getrangeCommand → memcpy). Слепое сканирование нельзя сделать безопасным. Замена детерминирована:

Скачать инструмент