.htaccess Upload — RCE через перезапись конфигурации Apache
Загрузка .htaccess позволяет выполнять PHP-код внутри файлов с произвольным расширением.
hardphpPro
Задача
# File Upload: RCE через `.htaccess`-оверрайд Apache
## Сценарий
Интернет-магазин SecureShop предоставляет авторизованным пользователям форму загрузки файлов. Загруженные файлы оседают в публично доступной директории, которую обслуживает веб-сервер Apache. Архитектура простая: клиент отправляет файл через multipart POST, сервер сохраняет его на диск под произвольным именем, после чего файл становится доступен по прямому URL.
Команда разработки реализовала загрузку «в лоб»: серверный код берёт имя из multipart-запроса, оборачивает в `basename()` (защита от path traversal в имени) и сохраняет файл. Никакой фильтрации содержимого, никакого allowlist расширений, никакого запрета на dotfiles — разработчики посчитали, что `basename` + случайный гость в директории «не страшно».
## Цель
1. Авторизуйтесь как обычный пользователь и найдите форму загрузки файлов.
2. Изучите, как Apache обрабатывает запросы к директории загрузок: какие локальные оверрайды конфигурации он умеет читать, и насколько строго сервер валидирует имена попадающих в эту директорию файлов.
3. Используйте локальный механизм оверрайдов Apache, чтобы превратить произвольное расширение в исполняемое как PHP.
4. Загрузите полезную нагрузку под этим расширением и получите `LAB_FLAG` через серверное исполнение.
## Теория
Apache построен на каскаде конфигурационных директив: глобальная конфигурация задаёт правила обработки запросов, а в каждой директории, где это разрешено опцией `AllowOverride`, может лежать локальный файл `.htaccess`. Этот файл переопределяет правила для конкретного каталога и его потомков — Apache читает его при каждом запросе в эту директорию.
Среди директив `.htaccess` есть мощные семейства, управляющие выбором обработчика для запроса:
- **`AddType`** — привязка MIME-типа к расширению. `AddType application/x-httpd-php .jpg` объявляет, что все файлы `.jpg` в директории отдаются с типом `application/x-httpd-php`, что в стандартной конфигурации Apache mod_php означает: «передавай через PHP-интерпретатор».
- **`AddHandler`** — прямое назначение обработчика. `AddHandler application/x-httpd-php .jpg` делает то же самое явным образом.
- **`SetHandler`** — глобальная привязка обработчика для всей директории. Самый агрессивный вариант.
Если атакующий получит возможность подложить `.htaccess` в каталог, обслуживаемый Apache, он может объявить любое расширение «исполняемым» как PHP. Это классическая двухходовка:
1. Сначала загружается управляющий файл `.htaccess`, переписывающий конфигурацию каталога.
2. Затем загружается полезная нагрузка с расширением, на которое теперь натравлен PHP-интерпретатор (например, `shell.jpg` с PHP-кодом внутри).
После двух загрузок обычный HTTP-запрос к файлу из директории загрузок превращается в исполнение кода — RCE с правами процесса Apache.
**Уязвимый PHP-паттерн:**
```php
// VULNERABILITY: имя файла берётся из multipart-запроса без фильтрации dotfiles
// и без allowlist расширений — .htaccess попадёт на диск под своим именем
$filename = basename($_FILES['file']['name']);
$destPath = $uploadsDir . '/' . $filename;
move_uploaded_file($_FILES['file']['tmp_name'], $destPath);
```
`basename()` снимает path traversal, но **не отсекает имена, начинающиеся с точки**: `basename('.htaccess')` возвращает `.htaccess`. Никакой проверки расширения, никакого `str_starts_with($filename, '.')` — управляющий файл Apache попадает на диск ровно туда, где он будет прочитан при следующем же HTTP-запросе.
### Условия эксплуатации
Для успешной атаки должны совпасть три фактора (все три выполнены в этой лабе):
1. Apache настроен с `AllowOverride` ≥ `FileInfo` для директории загрузок — позволяет `.htaccess`-директивам менять handler-mapping.
2. Обработчик загрузки не отбрасывает dotfiles и не делает allowlist расширений.
3. Имя файла берётся из клиентского запроса без перезаписи — `.htaccess` попадает на диск с этим именем.
### Таблица альтернативных техник под `.htaccess` upload
| Директива в `.htaccess` | Эффект |
|-------------------------|--------|
| `AddType application/x-httpd-php .jpg` | `.jpg` файлы в директории интерпретируются как PHP |
| `AddHandler application/x-httpd-php .jpg .gif .png` | то же для нескольких расширений сразу |
| `SetHandler application/x-httpd-php` | все файлы в директории, любое расширение |
| `Options +ExecCGI` + `AddHandler cgi-script .jpg` | альтернатива через CGI (если PHP отключён, но CGI есть) |
| `php_value auto_prepend_file evil.jpg` | автоматически подгружать `evil.jpg` перед каждым PHP-запросом в директории |
В этой лабе срабатывает самая прямая комбинация — `AddType application/x-httpd-php .jpg` + загрузка `shell.jpg` с PHP-однострочником.
## Точка входа атаки
| Параметр | Значение |
|----------|----------|
| Учётные данные | `demo` / `demo` |
| Форма загрузки | страница загрузки документов, поле `file`, multipart/form-data |
| Директория файлов | `/uploads/` (отдаётся Apache как часть веб-корня) |
| Уязвимое поведение | имя файла из `$_FILES['file']['name']` сохраняется как есть; нет фильтра dotfiles, нет allowlist расширений |
| Источник флага | переменная окружения `LAB_FLAG` процесса Apache, читается из PHP через `getenv("LAB_FLAG")` или `printenv` через shell |