mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
98 lines
6.7 KiB
Markdown
98 lines
6.7 KiB
Markdown
# LFI2RCE via Eternal waiting
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
## Podstawowe informacje
|
|
|
|
Domyślnie, gdy plik jest przesyłany do PHP (nawet jeśli nie jest to oczekiwane), generowany jest plik tymczasowy w `/tmp` o nazwie takiej jak **`php[a-zA-Z0-9]{6}`**, chociaż widziałem niektóre obrazy dockera, w których generowane pliki nie zawierają cyfr.
|
|
|
|
W przypadku lokalnego włączenia pliku, **jeśli uda ci się dołączyć ten przesłany plik, uzyskasz RCE**.
|
|
|
|
Zauważ, że domyślnie **PHP pozwala na przesyłanie tylko 20 plików w jednym żądaniu** (ustawione w `/etc/php/<version>/apache2/php.ini`):
|
|
```
|
|
; Maximum number of files that can be uploaded via a single request
|
|
max_file_uploads = 20
|
|
```
|
|
Również, **liczba potencjalnych nazw plików wynosi 62\*62\*62\*62\*62\*62 = 56800235584**
|
|
|
|
### Inne techniki
|
|
|
|
Inne techniki polegają na atakowaniu protokołów PHP (nie będziesz w stanie, jeśli kontrolujesz tylko ostatnią część ścieżki), ujawnianiu ścieżki pliku, nadużywaniu oczekiwanych plików lub **sprawieniu, by PHP doznało błędu segmentacji, aby przesyłane pliki tymczasowe nie zostały usunięte**.\
|
|
Ta technika jest **bardzo podobna do ostatniej, ale nie wymaga znalezienia zero day**.
|
|
|
|
### Technika wiecznego oczekiwania
|
|
|
|
W tej technice **musimy tylko kontrolować względną ścieżkę**. Jeśli uda nam się przesłać pliki i sprawić, by **LFI nigdy się nie kończyło**, będziemy mieli "wystarczająco dużo czasu", aby **brute-forcować przesłane pliki** i **znaleźć** dowolny z przesłanych.
|
|
|
|
**Zalety tej techniki**:
|
|
|
|
- Musisz tylko kontrolować względną ścieżkę wewnątrz include
|
|
- Nie wymaga nginx ani nieoczekiwanego poziomu dostępu do plików dziennika
|
|
- Nie wymaga 0 day, aby spowodować błąd segmentacji
|
|
- Nie wymaga ujawnienia ścieżki
|
|
|
|
**Główne problemy** tej techniki to:
|
|
|
|
- Potrzebne są konkretne pliki, aby były obecne (może być ich więcej)
|
|
- **Szaleńcza** ilość potencjalnych nazw plików: **56800235584**
|
|
- Jeśli serwer **nie używa cyfr**, całkowita potencjalna ilość wynosi: **19770609664**
|
|
- Domyślnie **tylko 20 plików** może być przesłanych w **jednym żądaniu**.
|
|
- **Maksymalna liczba równoległych pracowników** używanego serwera.
|
|
- Ten limit w połączeniu z poprzednimi może sprawić, że atak będzie trwał zbyt długo
|
|
- **Limit czasu dla żądania PHP**. Idealnie powinien być wieczny lub powinien zabić proces PHP bez usuwania tymczasowo przesłanych plików, w przeciwnym razie będzie to również problem
|
|
|
|
Jak więc możesz **sprawić, by include PHP nigdy się nie kończyło**? Po prostu przez dołączenie pliku **`/sys/kernel/security/apparmor/revision`** (**niestety niedostępny w kontenerach Docker...**).
|
|
|
|
Spróbuj to zrobić, po prostu wywołując:
|
|
```bash
|
|
php -a # open php cli
|
|
include("/sys/kernel/security/apparmor/revision");
|
|
```
|
|
## Apache2
|
|
|
|
Domyślnie, Apache obsługuje **150 równoczesnych połączeń**, zgodnie z [https://ubiq.co/tech-blog/increase-max-connections-apache/](https://ubiq.co/tech-blog/increase-max-connections-apache/) można zwiększyć tę liczbę do 8000. Postępuj zgodnie z tym, aby używać PHP z tym modułem: [https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04](https://www.digitalocean.com/community/tutorials/how-to-configure-apache-http-with-mpm-event-and-php-fpm-on-ubuntu-18-04).
|
|
|
|
Domyślnie, (jak mogę zobaczyć w moich testach), **proces PHP może trwać wiecznie**.
|
|
|
|
Zróbmy trochę matematyki:
|
|
|
|
- Możemy użyć **149 połączeń** do wygenerowania **149 \* 20 = 2980 plików tymczasowych** z naszym webshell.
|
|
- Następnie, użyj **ostatniego połączenia** do **brute-force** potencjalnych plików.
|
|
- Przy prędkości **10 żądań/s** czasy są:
|
|
- 56800235584 / 2980 / 10 / 3600 \~= **530 godzin** (50% szans w 265h)
|
|
- (bez cyfr) 19770609664 / 2980 / 10 / 3600 \~= 185h (50% szans w 93h)
|
|
|
|
> [!WARNING]
|
|
> Zauważ, że w poprzednim przykładzie **całkowicie DoSujemy innych klientów**!
|
|
|
|
Jeśli serwer Apache zostanie ulepszony i moglibyśmy nadużywać **4000 połączeń** (w połowie drogi do maksymalnej liczby). Moglibyśmy stworzyć `3999*20 = 79980` **plików** a **liczba** zostałaby **zmniejszona** do około **19.7h** lub **6.9h** (10h, 3.5h 50% szans).
|
|
|
|
## PHP-FMP
|
|
|
|
Jeśli zamiast używać regularnego modułu php dla apache do uruchamiania skryptów PHP, **strona internetowa używa** **PHP-FMP** (to poprawia wydajność strony internetowej, więc często można to znaleźć), można zrobić coś innego, aby poprawić tę technikę.
|
|
|
|
PHP-FMP pozwala na **konfigurację** **parametru** **`request_terminate_timeout`** w **`/etc/php/<php-version>/fpm/pool.d/www.conf`**.\
|
|
Ten parametr wskazuje maksymalną liczbę sekund **kiedy** **żądanie do PHP musi zakończyć się** (domyślnie nieskończoność, ale **30s, jeśli parametr jest odkomentowany**). Gdy żądanie jest przetwarzane przez PHP przez wskazaną liczbę sekund, jest **zabijane**. Oznacza to, że jeśli żądanie przesyłało pliki tymczasowe, ponieważ **przetwarzanie PHP zostało zatrzymane**, te **pliki nie zostaną usunięte**. Dlatego, jeśli możesz sprawić, aby żądanie trwało ten czas, możesz **wygenerować tysiące plików tymczasowych**, które nie zostaną usunięte, co **przyspieszy proces ich znajdowania** i zmniejsza prawdopodobieństwo DoS dla platformy poprzez wykorzystanie wszystkich połączeń.
|
|
|
|
Aby **unikać DoS**, załóżmy, że **atakujący będzie używał tylko 100 połączeń** w tym samym czasie, a maksymalny czas przetwarzania PHP przez **php-fmp** (`request_terminate_timeout`**)** wynosi **30s**. Dlatego liczba **plików tymczasowych**, które mogą być generowane **na sekundę** wynosi `100*20/30 = 66.67`.
|
|
|
|
Następnie, aby wygenerować **10000 plików**, atakujący potrzebowałby: **`10000/66.67 = 150s`** (aby wygenerować **100000 plików** czas wyniósłby **25min**).
|
|
|
|
Następnie atakujący mógłby użyć tych **100 połączeń** do przeprowadzenia **brute-force**. Zakładając prędkość 300 req/s, czas potrzebny do wykorzystania tego jest następujący:
|
|
|
|
- 56800235584 / 10000 / 300 / 3600 \~= **5.25 godzin** (50% szans w 2.63h)
|
|
- (z 100000 plikami) 56800235584 / 100000 / 300 / 3600 \~= **0.525 godzin** (50% szans w 0.263h)
|
|
|
|
Tak, możliwe jest wygenerowanie 100000 plików tymczasowych na instancji średniej wielkości EC2:
|
|
|
|
<figure><img src="../../images/image (240).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
> [!WARNING]
|
|
> Zauważ, że aby wywołać limit czasu, **wystarczy uwzględnić podatną stronę LFI**, aby weszła w wieczną pętlę dołączania.
|
|
|
|
## Nginx
|
|
|
|
Wygląda na to, że domyślnie Nginx obsługuje **512 równoległych połączeń** w tym samym czasie (i ta liczba może być poprawiona).
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|