
pfSense CE 2.9.0-DEVELOPMENT — высокий уровень — удалённый — RCE — limiter number dnctl
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · pfsense-limiter-number
Разбор: https://abraxaslabs.tech/research/pfsense-limiter-number
Класс: RCE Доступ: Удалённый
pfSense CE 2.9.0-DEVELOPMENT (9363ac5) - pfsense.org
Ограничители Traffic Shaper при редактировании передают скрытое поле number. Создание перезаписывает это число через dnpipe_find_nextnumber(). Редактирование — нет. validate_input никогда не проверяет number. GetNumber() без кавычек конкатенируется в dnctl pipe|sched|queue delete. PHP mwexec — это /bin/sh -c. Привилегия — page-firewall-trafficshaper-limiter, а не Diagnostics: Command.
| ID | CVE пока нет |
| Класс | RCE |
| Доступ | Удалённый (аутентифицированный WebGUI) |
| CWE | CWE-78 |
| CVSS | Высокий: 8.8 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| Продукт | pfSense CE |
| Затронуто | 2.9.0-DEVELOPMENT (9363ac5b8651a1c7a333180425ce7719070f95f9) поле number ограничителя |
| Аутентификация | Сессия WebGUI с page-firewall-trafficshaper-limiter |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1 |
Я зафиксировал публичный master 9363ac5. Лаборатория — это PHP-гаджет с зафиксированными ReadConfig / SetNumber / delete_queue. Loopback 127.0.0.1:18840.
| Метод | Точка сброса | Привилегия |
|---|---|---|
Создать ограничитель, отправить POST save с подконтрольным атакующему number, затем удалить этот ограничитель | mwexec("/sbin/dnctl pipe delete " . $this->GetNumber()) (shaper.inc:3820) | Целостность (доказано в лаборатории): root shell. Лаборатория: edit-delete записал свидетельство (edit-delete-exec=yes). Перезапись при создании и путь apply-file не записали ничего. |
| Тот же root shell | файловая система хоста | Разведка (предположительно): config.xml, ключи. |
Root shell или dnctl с подконтрольными номерами | dummynet | Доступность (предположительно): нарушение работы ограничителя / dummynet. |
Доказано в лаборатории vs предположительно: перезапись при создании (без свидетельства), путь apply-file (dnctl файла, без свидетельства) и exec при edit-delete (со свидетельством) доказаны в лаборатории. Разведка файловой системы выведена из root PHP-FPM.
Требуется: сессия WebGUI с page-firewall-trafficshaper-limiter. CSRF при POST save. Удаление — GET action=delete.
| Поверхность | Лаборатория |
|---|---|
| Путь создания | dnpipe_find_nextnumber() перезаписывает, create-overwrites=yes |
| Путь применения | dnctl для /tmp/rules.limiter, имя файла не контролируется пользователем, apply-file=yes |
| Набор символов имени ограничителя | ^[a-zA-Z0-9_-]+$ |
| Без аутентификации | закрыто |
| Diagnostics: Command | остаётся закрытым, если не предоставлено дополнительно |
Параметры AQM в /tmp/rules.limiter — это дополнительный язык dummynet, а не данная недоделка.
cd lab
./run.sh
Loopback 127.0.0.1:18840. Проект Compose pfsense-limiter-number. Тег образа pfsense-limiter-number:2.9.0-dev. Свидетель PFSENSE-LIMITER-NUMBER-WITNESS. Последняя строка:
SUCCESS PFSENSE-LIMITER-NUMBER create-overwrites=yes apply-file=yes edit-delete-exec=yes PFSENSE-LIMITER-NUMBER-WITNESS
Приводить GetNumber() к int перед каждым вызовом dnctl. Игнорировать POST-параметр number при редактировании или проверять его диапазон по актуальному id dummynet. Создание уже перезаписывает; сделать то же самое при редактировании.
9363ac5b8651a1c7a333180425ce7719070f95f9shaper.inc delete_queue / GetNumberfirewall_shaper_vinterface.php