
ProFTPD 1.3.9d — высокий — удалённый — остаточные привилегии / запись файла — SITE COPY dest следует по символической ссылке
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · proftpd-site-copy-dest-follow
Класс: Остаточные привилегии / запись в файл Достижимость: Удалённая
ProFTPD 1.3.9d (f59f248) - proftpd.org
Contrib mod_copy SITE COPY проверяет dest через Limit с помощью dir_canonical_vpath (неразрешённый путь). Затем pr_fs_copy_file2 выполняет open для dest без O_NOFOLLOW, поэтому символическая ссылка dest разыменовывается. FTP STOR проверяет через Limit разрешённый путь (dir_realpath / dir_best_path). SITE COPY dest — нет.
Аутентифицированный FTP-пользователь перезаписывает файл, запись в который запрещена, направив символическую ссылку dest на него и выполнив SITE COPY. Прямой STOR и SITE COPY на жертву остаются 550. STOR / SITE RMDIR / RMD ссылки остаются 550. DELE удаляет только узел ссылки. Без шелла. Unix DAC по-прежнему применяется.
Это инверсия публичного Issue 2095 (пропуск READ источника SITE COPY). Это отличается от публичного Issue 2256 (разыменование символической ссылки RNTO EXDEV). Этот остаток — dest SITE COPY при каждой копии, а не только при EXDEV.
| ID | пока нет CVE |
| Класс | Остаточные привилегии / запись в файл |
| Достижимость | Удалённая (аутентифицированный FTP) |
| CWE | CWE-59, CWE-863 |
| CVSS | High: 7.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N |
| Продукт | ProFTPD |
| Затронуто | 1.3.9d тег v1.3.9d (f59f248e26bdfa514443e42bf72a145641df635d) contrib mod_copy |
| Аутентификация | аутентифицированный FTP (mod_copy загружен, CopyEngine по умолчанию включён). Для создания SITE SYMLINK также нужен contrib mod_site_misc, если ссылка ещё не существует |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1 |
Кто: аутентифицированный FTP-пользователь. mod_copy загружен. Символическая ссылка dest в каталоге с разрешённой записью (SITE SYMLINK или уже существующая ссылка). SITE SYMLINK src использует dir_check_canon G_READ, поэтому для создания ссылки на файл-жертву нужен READ на этот файл. Разделение: READ разрешён, WRITE запрещён. UID сессии всё ещё должен иметь возможность Unix-записи в цель.
| Метод | Точка сброса | Привилегия |
|---|---|---|
| SITE SYMLINK (или существующая ссылка) в каталоге с разрешённой записью, цель которой — файл с запрещённой записью, в который UID может писать на уровне Unix; SITE COPY читаемого src на эту ссылку | pr_fsio_open dest разыменовывает | Целостность (доказано в лаборатории): усечение/перезапись файла, запрещённого Limit, от имени UID сессии. Лаборатория: /secret/victim перешёл из ORIGINAL в witness после SITE COPY /readable/src.txt /upload/link. Прямой SITE COPY на /secret/victim остался 550. |
| SITE RMDIR той же ссылки | dir_check_canon -> dir_best_path | Закрыто (доказано в лаборатории): 550 RMDIR /upload/link: Operation not permitted. Жертва не тронута. |
| Core RMD той же ссылки | dir_best_path + WRITE | Закрыто (доказано в лаборатории): 550 Permission denied. Жертва не тронута. |
| STOR на ссылку dest | dir_best_path + WRITE | Закрыто (доказано в лаборатории): STOR /upload/link -> 550. Жертва не тронута. |
| DELE ссылки dest | unlink узла ссылки | Закрыто для жертвы (доказано в лаборатории): DELE удалил только ссылку; жертва по-прежнему содержала witness. |
DefaultRoot jail на хостовый /etc | chroot | Закрыто. Unix DAC по-прежнему применяется. Без неаутентифицированного доступа. Без шелла. |
Доказано в лаборатории vs предположено: перезапись через неразрешённую символическую ссылку dest, отклонённые STOR/RMDIR/RMD и DELE-только-ссылки доказаны в лаборатории. Неаутентифицированный доступ и Unix DAC остаются предположениями из модели auth/chroot.
Я зафиксировал proftpd/proftpd v1.3.9d (f59f248). Стандартный core FTP с примером basic.conf не имел неопубликованных Crit/High. Следующим был contrib mod_copy.
copy_copy (contrib/mod_copy.c) строит dest с помощью dir_canonical_vpath, затем dir_check(..., G_WRITE, to) по этой неразрешённой строке. pr_fs_copy_file2 (src/fsio.c) комментирует, что stat/open разыменовывают символическую ссылку dest, затем pr_fsio_open(dst, O_WRONLY|O_CREAT|O_NONBLOCK) без O_NOFOLLOW.
Публичный Issue 2095 — это пропуск READ источника при SITE COPY. Пропускаю именно этот баг. Публичный Issue 2256 — это разыменование RNTO EXDEV. Этот остаток — dest SITE COPY при каждой копии.
Рекурсивное разыменование SITE RMDIR было отброшено как родительское: SITE RMDIR использует dir_check_canon / dir_best_path, которые разрешают символическую ссылку до Limit. Лаборатория подтвердила, что SITE RMDIR и core RMD ссылки dest остаются запрещёнными.
Уже зафиксированные неверные пути: трактовка Limit dest как разрешённого, потому что STOR разрешён; трактовка Issue 2256 как этого остатка; утверждение, что SITE RMDIR обходит жертву. Театр: обратный шелл. Оракул — /secret/victim, содержащий witness после SITE COPY через /upload/link, при том что STOR ссылки по-прежнему 550.
python3 proftpd-site-copy-dest-follow-Abraxas-Labs.py
или:
cd lab
./run.sh
Loopback FTP 127.0.0.1:18720, passive 18721-18730. Compose-проект proftpd-site-copy-dest-follow. Witness PROFTPD-SITE-COPY-DEST-FOLLOW-WITNESS. Последняя строка:
SUCCESS PROFTPD-SITE-COPY-DEST-FOLLOW victim-has-witness=yes stor-secret=denied stor-link=denied site-rmdir-walk=no rmd-walk=no dele-victim=intact PROFTPD-SITE-COPY-DEST-FOLLOW-WITNESS
Проверять через Limit разрешённый dest (dir_realpath / dir_best_path) или открывать dest с O_NOFOLLOW. STOR уже проверяет через Limit разрешённый путь.
Приём вендором: [email protected]. Не открывайте публичный GitHub issue в proftpd/proftpd.
f59f248e26bdfa514443e42bf72a145641df635d)contrib/mod_copy.c copy_copysrc/fsio.c pr_fs_copy_file2<Limit READ>GNU Affero GPL v3.0. См. LICENSE. Только loopback-лаборатория. Без гарантий.