
Некорректная нейтрализация специальных элементов, используемых в SQL-команде («SQL-инъекция»), в устройствах серии SonicWall SMA1000 позволяет удалённому аутентифицированному злоумышленнику с правами администратора только для чтения повысить свои привилегии до уровня основного администратора.
Уязвимость слепой SQL-инъекции после аутентификации в консоли управления SonicWall SMA 8200v (порт 8443) позволяет любому аутентифицированному администратору — включая учётные записи с низкими привилегиями только для чтения — извлечь SHA-512 хэш пароля главного администратора из файла конфигурации устройства. Поскольку SonicWall использует одни и те же учётные данные как для администратора консоли управления, так и для учётной записи root операционной системы, взлом этого хэша даёт полный доступ уровня root к устройству.
Классификация: Повышение привилегий (от администратора с низкими привилегиями до Root) CVSS 3.1: 7.2 (Высокий) — AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H Сложность атаки: Низкая (автоматизированный PoC завершает извлечение за ~60-90 минут) Предварительные условия: Любые действительные учётные данные консоли управления (включая учётные записи только для чтения)
| Компонент | Сведения |
|---|---|
| Платформа | SonicWall SMA 8200v (виртуальное устройство) |
| Прошивка | 12.5.0-02283 (подтверждено); вероятно, все версии 12.x |
| Сервис | Консоль управления — Jetty + Struts 2 (порт 8443) |
| Конечная точка | POST /activeUsers.action |
| Уязвимые параметры | realmFilter, communityFilter (межпараметрические) |
| Класс первопричины | com.aventail.mgmt.sql.Sql.safeParam() |
| База данных | MariaDB 10.11.14, пользователь DbAdmin (ALL PRIVILEGES + FILE) |
| Целевой файл | /usr/local/app/mgmt-server/datastore/active/sysconf/avconfig.xml |
Консоль управления формирует SQL-запросы для панели активных пользователей с помощью вспомогательного метода safeParam() в классе com.aventail.mgmt.sql.Sql. Этот метод экранирует одинарные кавычки (') и двойные кавычки (") путём их удвоения, но не экранирует символы обратной косой черты (\).
В MySQL/MariaDB обратная косая черта является символом экранирования по умолчанию внутри строковых литералов. Последовательность \' заставляет базу данных интерпретировать одинарную кавычку как литеральный символ, а не как завершитель строки. Это означает, что обратная косая черта в конце значения параметра экранирует закрывающую кавычку, которую добавляет приложение, в результате чего строковый литерал SQL расширяется в соседний синтаксис.
Пробел в санитизации:```
Input: test
safeParam output: test\ (backslash NOT escaped)
In SQL: ... rt.name='test') AND (ct.name='...'
^^ backslash escapes the closing quote
The closing `'` after `test\` is consumed as a literal quote character within the string, so the SQL string literal extends across the `) AND (ct.name='` boundary and into the next parameter's value, where attacker-controlled SQL can be injected.
### 3.2 Injection Mechanics: Cross-Parameter Technique
The `activeUsers.action` endpoint accepts multiple filter parameters that are interpolated into a single SQL WHERE clause. The relevant parameters are `realmFilter` and `communityFilter`, which appear in a query structured approximately as:```sql
SELECT ... FROM ...
WHERE ...
AND (rt.name='<realmFilter>')
AND (ct.name='<communityFilter>')
...
Настройка параметров атаки:
| Параметр | Значение | Назначение |
|---|---|---|
realmFilter | test\ | Завершающий обратный слэш экранирует закрывающую кавычку, расширяя строковый литерал через границу AND |
communityFilter | )) OR (SELECT IF(<условие>,SLEEP(N),0))-- x | Закрывает открытые скобки, внедряет условный SLEEP, закомментировывает остаток |
Результирующий SQL после интерполяции:```sql WHERE ... AND (rt.name='test') AND (ct.name=' )) OR (SELECT IF(,SLEEP(N),0))-- x')
Разбивая это:
1. `rt.name='test\')` — `\` экранирует `'`, поэтому строка здесь не закрывается
2. `AND (ct.name='` — становится частью строкового значения (литеральный текст)
3. Строка наконец закрывается на следующем `'` (из начала `communityFilter`)
4. `))` — закрывает две открытые круглые скобки из структуры WHERE-условия
5. `OR (SELECT IF(...))` — внедряет условие слепой SQL-инъекции
6. `-- x` — закомментировывает остаток SQL (`')` и другие условия)
### 3.3 Извлечение данных на основе временной задержки
Поскольку обработка ошибок Struts 2 в приложении корректно перехватывает SQL-исключения (всегда возвращая HTTP 200 с тем же содержимым страницы независимо от успеха или неудачи запроса), методы извлечения на основе ошибок и UNION-запросов неприменимы. Инъекция эксплуатируется с помощью техники слепой временной задержки:
- **Условие TRUE:** `IF(<условие>, SLEEP(N), 0)` — ответ задерживается на время SLEEP, умноженное на количество строк в результирующем наборе
- **Условие FALSE:** Без SLEEP — ответ возвращается за ~200-500 мс
Функция SLEEP выполняется для каждой строки при оценке WHERE-условия. При типичной таблице мониторинга, содержащей 30-300+ строк, даже небольшое значение SLEEP (например, 0,3 с) даёт чётко различимую задержку (10-100 с для TRUE против <1 с для FALSE).
Каждый символ целевых данных извлекается с помощью бинарного поиска по диапазону ASCII:```sql
ORD(SUBSTRING((<extraction_expr>), <position>, 1)) > <midpoint>
Для этого требуется максимум 7 запросов на символ (log2(128) = 7), что даёт ~686 запросов для 98-символьного хэша SHA-512.
PRIVILEGE ESCALATION CHAIN
============================================================================
[1] Authenticate Low-privilege admin (e.g., "readonly") | authenticates to management console on port 8443 | using "Local Authentication" realm v [2] SQL Injection Cross-parameter blind SQLi via activeUsers.action | realmFilter backslash + communityFilter payload | Condition: IF(, SLEEP(N), 0) v [3] LOAD_FILE() MariaDB DbAdmin user has FILE privilege | secure_file_priv=NULL does NOT block reads | avconfig.xml is group-readable (mode 664) v [4] Locate Hash LOCATE('consoleMode', file) anchors to admin section | LOCATE('', file, anchor) finds hash element | SUBSTRING + SUBSTRING_INDEX extracts hash value v [5] Extract Hash Binary search extracts hash char-by-char | ~98 chars * ~7 requests = ~686 requests | Output: $6$$ (SHA-512 crypt) v [6] Crack Hash hashcat -m 1800 / john --format=sha512crypt | Admin password = Root SSH password (by design) v [7] Full Compromise SSH as root, management console as admin Complete appliance takeover
### 4.2 Шаг 1: Аутентификация
Консоль управления SMA поддерживает два домена аутентификации:
| Идентификатор домена | Отображаемое имя | Пользователи |
|----------|-------------|-------|
| *(пусто)* | Консоль управления | Только основная учётная запись администратора |
| `AMCAuthRealm` / `Local Authentication` | Локальная аутентификация | Дополнительные учётные записи администратора (readonly, custom) |
Для атаки требуется только действительные учётные данные для **любой** учётной записи с доступом к консоли управления. Учётной записи "readonly" — предназначенной только для мониторинга без возможности изменения конфигурации — достаточно.