
Воспроизводимый Docker-лабораторный стенд + эксплойт на raw-сокетах для CVE-2015-3306 (ProFTPD mod_copy, произвольное копирование файлов до аутентификации) — учебное упражнение по анализу патчей
Полностью воспроизводимая лаборатория и написанный вручную эксплойт для CVE-2015-3306 — создано как учебное упражнение по исследованию уязвимостей: сравнение патчей, ручной триггер и разработка эксплойта на сырых сокетах.
Модуль mod_copy в ProFTPD реализует пару команд SITE CPFR / SITE CPTO,
которые копируют файлы на стороне сервера без передачи данных клиенту.
В версии 1.3.5 ни один из обработчиков не проверял, аутентифицирована ли сессия. Модуль просто предполагал, что «никто не будет отправлять команды SITE до входа в систему» — ошибочное предположение, которое стало CVE. Любой неаутентифицированный клиент мог скопировать любой файл, читаемый процессом сервера, в любое место, доступное для записи.
Исправление (коммит 212d54271f, выпущено в 1.3.5a) делает две вещи:
copy_cpfr и :
copy_cptoauthenticated = get_param_ptr(cmd->server->conf, "authenticated", FALSE);
if (authenticated == NULL || *authenticated == FALSE) {
pr_response_add_err(R_530, _("Please login with USER and PASS"));
errno = EPERM;
return PR_ERROR(cmd);
}
CopyEngine on|off — ранее модуль нельзя было даже
отключить в сборках, где он поставлялся.Полный unified diff находится в patch.diff. Чтение патчей — это
навык: исправление говорит вам, где была рана.
Dockerfile компилирует ProFTPD 1.3.5 (последний уязвимый релиз) из
официального исходного tarball с включённым mod_copy:
docker build -t proftpd-135 .
docker run -d --name lab135 -p 127.0.0.1:2121:21 -p 127.0.0.1:30000-30010:30000-30010 proftpd-135
docker exec lab135 chmod 777 /home/ftp
PassivePorts в proftpd.conf фиксирует канал данных — двухканальная
архитектура FTP (управление + динамические данные) — причина, по которой
наивные маппинги контейнеров не работают: управляющий порт работает, порт
данных — нет.
exploit.py использует сырые сокеты — без ftplib, потому что библиотеки
скрывают протокол, а скрытие протокола — это именно то, с чем мы боремся:
SITE CPFR /etc/segredo.txt -> 350 (USER/PASS не отправлены: это И ЕСТЬ уязвимость)
SITE CPTO /home/ftp/... -> 250 (произвольное копирование выполнено)
USER ftp / PASS ... -> 230 (вход — это только путь эксфильтрации)
PASV / RETR -> 150 -> 226 (флаг захвачен)
DELE -> 250 (очистка: никаких IOC не осталось)
AllowOverwrite, маппинги портов) определяет конечное
воздействие.time.time_ns(), а не time.time())
и отсутствие зависимости от остаточного состояния.RETR
отвечает дважды: 150, затем 226. Считайте оба ответа перед следующей командой.-d10) точно скажет вам, какая
проверка сработала.Только для образовательных целей и авторизованного использования в лаборатории. Запуск этого против систем, которыми вы не владеете или на тестирование которых не имеете письменного разрешения, незаконен.