mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
98 lines
10 KiB
Markdown
98 lines
10 KiB
Markdown
# LFI2RCE через Вічне очікування
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## Основна інформація
|
||
|
||
За замовчуванням, коли файл завантажується в PHP (навіть якщо він цього не очікує), він створить тимчасовий файл у `/tmp` з ім'ям, таким як **`php[a-zA-Z0-9]{6}`**, хоча я бачив деякі образи docker, де згенеровані файли не містять цифр.
|
||
|
||
У випадку локального включення файлу, **якщо вам вдасться включити цей завантажений файл, ви отримаєте RCE**.
|
||
|
||
Зверніть увагу, що за замовчуванням **PHP дозволяє завантажувати лише 20 файлів в одному запиті** (встановлено в `/etc/php/<version>/apache2/php.ini`):
|
||
```
|
||
; Maximum number of files that can be uploaded via a single request
|
||
max_file_uploads = 20
|
||
```
|
||
Також, **кількість потенційних імен файлів становить 62\*62\*62\*62\*62\*62 = 56800235584**
|
||
|
||
### Інші техніки
|
||
|
||
Інші техніки базуються на атаці протоколів PHP (ви не зможете цього зробити, якщо контролюєте лише останню частину шляху), розкритті шляху до файлу, зловживанні очікуваними файлами або **змушуючи PHP зазнати сегментаційної помилки, щоб завантажені тимчасові файли не були видалені**.\
|
||
Ця техніка **дуже схожа на останню, але не вимагає знаходження нульового дня**.
|
||
|
||
### Техніка вічного очікування
|
||
|
||
У цій техніці **нам потрібно лише контролювати відносний шлях**. Якщо нам вдасться завантажити файли і зробити так, щоб **LFI ніколи не закінчувався**, у нас буде "досить часу", щоб **брутфорсити завантажені файли** і **знайти** будь-який з них.
|
||
|
||
**Переваги цієї техніки**:
|
||
|
||
- Вам потрібно лише контролювати відносний шлях всередині включення
|
||
- Не вимагає nginx або несподіваного рівня доступу до лог-файлів
|
||
- Не вимагає нульового дня для викликання сегментаційної помилки
|
||
- Не вимагає розкриття шляху
|
||
|
||
**Основні проблеми** цієї техніки:
|
||
|
||
- Потрібні специфічні файли для присутності (може бути більше)
|
||
- **Безумна** кількість потенційних імен файлів: **56800235584**
|
||
- Якщо сервер **не використовує цифри**, загальна потенційна кількість становить: **19770609664**
|
||
- За замовчуванням **можна завантажити лише 20 файлів** в **одному запиті**.
|
||
- **Максимальна кількість паралельних робітників** використовуваного сервера.
|
||
- Це обмеження разом з попередніми може зробити цю атаку занадто тривалою
|
||
- **Тайм-аут для запиту PHP**. В ідеалі це має бути вічним або має вбивати процес PHP без видалення тимчасово завантажених файлів, якщо ні, це також буде проблемою
|
||
|
||
Отже, як ви можете **зробити так, щоб включення PHP ніколи не закінчувалося**? Просто включивши файл **`/sys/kernel/security/apparmor/revision`** (**на жаль, не доступний у контейнерах Docker...**).
|
||
|
||
Спробуйте це, просто викликавши:
|
||
```bash
|
||
php -a # open php cli
|
||
include("/sys/kernel/security/apparmor/revision");
|
||
```
|
||
## Apache2
|
||
|
||
За замовчуванням, Apache підтримує **150 одночасних з'єднань**, згідно з [https://ubiq.co/tech-blog/increase-max-connections-apache/](https://ubiq.co/tech-blog/increase-max-connections-apache/) це число можна збільшити до 8000. Слідкуйте за цим, щоб використовувати PHP з цим модулем: [https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04](https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04).
|
||
|
||
За замовчуванням, (як я можу бачити в своїх тестах), **PHP процес може тривати вічно**.
|
||
|
||
Давайте зробимо деякі розрахунки:
|
||
|
||
- Ми можемо використовувати **149 з'єднань** для генерації **149 \* 20 = 2980 тимчасових файлів** з нашим веб-шеллом.
|
||
- Потім, використати **остання з'єднання** для **брутфорсу** потенційних файлів.
|
||
- При швидкості **10 запитів/с** часи такі:
|
||
- 56800235584 / 2980 / 10 / 3600 \~= **530 годин** (50% шанс за 265 годин)
|
||
- (без цифр) 19770609664 / 2980 / 10 / 3600 \~= 185 годин (50% шанс за 93 години)
|
||
|
||
> [!WARNING]
|
||
> Зверніть увагу, що в попередньому прикладі ми **повністю DoS-имо інших клієнтів**!
|
||
|
||
Якщо сервер Apache буде покращено і ми зможемо зловживати **4000 з'єднаннями** (половина від максимальної кількості). Ми могли б створити `3999*20 = 79980` **файлів** і **число** зменшиться до приблизно **19.7 годин** або **6.9 годин** (10 годин, 3.5 години 50% шанс).
|
||
|
||
## PHP-FMP
|
||
|
||
Якщо замість використання звичайного php моду для apache для виконання PHP скриптів **веб-сторінка використовує** **PHP-FMP** (це покращує ефективність веб-сторінки, тому його часто можна знайти), є ще щось, що можна зробити для покращення техніки.
|
||
|
||
PHP-FMP дозволяє **налаштувати** **параметр** **`request_terminate_timeout`** в **`/etc/php/<php-version>/fpm/pool.d/www.conf`**.\
|
||
Цей параметр вказує максимальну кількість секунд **коли** **запит до PHP повинен завершитися** (безкінечно за замовчуванням, але **30 секунд, якщо параметр не закоментований**). Коли запит обробляється PHP, вказана кількість секунд, він **вбивається**. Це означає, що якщо запит завантажував тимчасові файли, тому що **обробка php була зупинена**, ці **файли не будуть видалені**. Отже, якщо ви можете зробити запит тривати цей час, ви можете **згенерувати тисячі тимчасових файлів**, які не будуть видалені, що **прискорить процес їх знаходження** і зменшує ймовірність DoS для платформи, споживаючи всі з'єднання.
|
||
|
||
Отже, щоб **уникнути DoS**, припустимо, що **зловмисник буде використовувати лише 100 з'єднань** одночасно, а максимальний час обробки php за **php-fmp** (`request_terminate_timeout`**)** становить **30 секунд**. Отже, кількість **тимчасових файлів**, які можуть бути згенеровані **за секунду**, становить `100*20/30 = 66.67`.
|
||
|
||
Тоді, щоб згенерувати **10000 файлів**, зловмиснику знадобиться: **`10000/66.67 = 150 секунд`** (щоб згенерувати **100000 файлів**, час становитиме **25 хвилин**).
|
||
|
||
Тоді зловмисник міг би використовувати ці **100 з'єднань** для виконання **брутфорсу**. Припускаючи швидкість 300 запитів/с, час, необхідний для експлуатації цього, такий:
|
||
|
||
- 56800235584 / 10000 / 300 / 3600 \~= **5.25 години** (50% шанс за 2.63 години)
|
||
- (з 100000 файлами) 56800235584 / 100000 / 300 / 3600 \~= **0.525 години** (50% шанс за 0.263 години)
|
||
|
||
Так, можливо згенерувати 100000 тимчасових файлів на середньому EC2 екземплярі:
|
||
|
||
<figure><img src="../../images/image (240).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
> [!WARNING]
|
||
> Зверніть увагу, що для активації тайм-ауту було б **досить включити вразливу LFI сторінку**, щоб вона потрапила в безкінечний цикл включення.
|
||
|
||
## Nginx
|
||
|
||
Схоже, що за замовчуванням Nginx підтримує **512 паралельних з'єднань** одночасно (і це число можна покращити).
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|