LFI2RCE via Eternal waiting

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Інші способи підтримки HackTricks:

Основна інформація

За замовчуванням, коли файл завантажується в 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 ніколи не завершується, у нас буде "достатньо часу" для перебору завантажених файлів та знаходження будь-якого з завантажених.

Переваги цієї техніки:

  • Вам потрібно лише контролювати відносний шлях всередині include

  • Не потребує nginx або неочікуваного рівня доступу до файлів журналу

  • Не потребує 0-дня для виклику сегментаційної помилки

  • Не потребує розкриття шляху

Основні проблеми цієї техніки:

  • Потрібно, щоб були присутні конкретні файли (їх може бути більше)

  • Божевільна кількість потенційних імен файлів: 56800235584

  • Якщо сервер не використовує цифри, загальна потенційна кількість становить: 19770609664

  • За замовчуванням лише 20 файлів можуть бути завантажені за один запит.

  • Максимальна кількість паралельних робітників використовуваного сервера.

  • Це обмеження разом з попередніми може зробити цю атаку занадто тривалою

  • Тайм-аут для запиту PHP. Ідеально це повинно бути вічним або повинно завершувати процес PHP без видалення тимчасово завантажених файлів, якщо ні, це також буде проблемою

Отже, як ви можете зробити включення PHP ніколи не завершується? Просто включивши файл /sys/kernel/security/apparmor/revision (на жаль, недоступний в контейнерах Docker). Спробуйте це просто викликавши:

php -a # open php cli
include("/sys/kernel/security/apparmor/revision");

Apache2

За замовчуванням Apache підтримує 150 одночасних підключень, за посиланням 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.

За замовчуванням (як я бачу в моїх тестах), PHP-процес може тривати вічно.

Зробимо деякі обчислення:

  • Ми можемо використовувати 149 підключень, щоб згенерувати 149 * 20 = 2980 тимчасових файлів з нашим веб-шеллом.

  • Потім використовуйте останнє підключення, щоб брутфорсити потенційні файли.

  • Зі швидкістю 10 запитів/с час складає:

  • 56800235584 / 2980 / 10 / 3600 ~= 530 годин (50% шансів за 265 годин)

  • (без цифр) 19770609664 / 2980 / 10 / 3600 ~= 185 годин (50% шансів за 93 години)

Зверніть увагу, що в попередньому прикладі ми повністю DoSing інших клієнтів!

Якщо сервер 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:

Зверніть увагу, що для того, щоб спрацював таймаут, буде достатньо включити уразливу сторінку LFI, щоб вона потрапила в вічний цикл включення.

Nginx

Здається, за замовчуванням Nginx підтримує 512 паралельних підключень одночасно (і це число можна покращити).

Last updated