In che modo OWASP ZAP trova Reflected XSS?

0

Che cosa sto facendo:

Sto usando OWASP Zap per trovare vulnerabilità in un sito (ho il consenso del proprietario) e Zap ha scoperto una vulnerabilità legata all'XSS riflessa dopo aver eseguito una scansione attiva su una richiesta POST. Mi ha detto che la variabile "cn" (il nome utente) era vulnerabile a XSS riflesso e che il payload "><script>alert(1);</script> avrebbe funzionato.

La mia procedura:

Sono andato avanti e ho cercato di inserirlo nel campo di input chiamato "cn". Il campo di immissione aveva una lunghezza massima di 12, sono andato avanti e ho fatto un rapido controllo dell'elemento e l'ho modificato. Quindi ho inserito il payload, inserito un valore casuale per il campo di immissione della password e ho fatto clic su submit.

Il risultato:

Purtroppo non è stata visualizzata una finestra di avviso, ma solo un nome utente e una password errati. Ho notato che un po 'di "> è apparso dopo aver inserito il payload. Quando ho esaminato ciò ho scoperto che il tag dello script aveva causato il "> da analizzare come caratteri normali. <input type="text" name="cn" size="20" maxlength="20" value="<script>alert(1);</script>"> è l'html. Anche se "> non avrebbe dovuto modificare il js.

Conclusione

AGGIORNAMENTO: Quindi, dopo aver riflettuto su questo nella doccia, mi sono reso conto dell'intero punto dell'XSS riflesso ... che il valore fornito all'utente doveva essere effettivamente riflesso. Il parametro un non è mai stato effettivamente restituito a me. Ma questo continua a non rispondere alla domanda ... perché ZAP lo ha rilevato come una vulnerabilità XSS quando non c'è chiaramente alcun XSS?

    
posta CoderPE 09.11.2018 - 02:08
fonte

1 risposta

8

Questi controlli automatici funzionano inserendo un tag script contenente un token casuale in ogni campo. Ad esempio, /someRequest?foo=x&bar=y potrebbe diventare:

GET /someRequest?foo=<script>alert("147230578")</script>&bar=<script>alert("561972456")</script>

Mantiene una mappa dei campi e i valori casuali scelti (in questo caso foo = 147230578, bar = 561972456) per tracciare quale parametro è iniettabile.

Quindi controlla se <script>alert("147230578")</script> o <script>alert("561972456")</script> appaiono nella pagina senza codifica . Se la stringa viene trovata, sa che XSS è molto probabile. In caso contrario, non è stato visualizzato nella pagina o è stato codificato in HTML.

Nel tuo caso, ha scoperto che se le stringhe venivano riflesse e identificava il campo iniettabile. Il motivo per cui non è stato eseguito è che il tag script è stato iniettato in un attributo HTML.

Quindi, osservando la tua iniezione:

<input type="text" name="cn" size="20" maxlength="20" value="<script>alert(1);</script>">

Ciò che accade qui è che l'HTML è malformato, quindi il renderer del browser cerca semplicemente di sfruttarlo al meglio, ignora entrambi i tag e chiude tutto dopo </script> . Quindi vede "> che assume è contenuto e lo mostra nella pagina.

Se invece inseriamo "><script>alert(1)</script> nel parametro, otteniamo questo:

<input type="text" name="cn" size="20" maxlength="20" value=""><script>alert(1)</script>">

Questa volta il tag di input è chiuso, il che fa sì che il tag script venga eseguito. XSS di successo! Di nuovo, il "> alla fine viene trattato come contenuto.

Per un giro bonus, cosa potremmo fare se il parametro vulnerabile non consente l'uso di parentesi triangolari? Dato che siamo già in un attributo, possiamo manipolare l'elemento input in cui ci stiamo iniettando per eseguire lo script:

" onmouseenter="alert(1)" x="

Questo crea il seguente output:

<input type="text" name="cn" size="20" maxlength="20" value="" onmouseenter="alert(1)" x="">

Si noti che l'attributo x non fa nulla, è solo lì per permetterci di mantenere un HTML valido; gli attributi sconosciuti sono semplicemente ignorati.

In questo caso, quando il mouse dell'utente entra nell'elemento di input, esegue JavaScript e otteniamo di nuovo XSS.

Ma richiede l'interazione dell'utente fa schifo! Potremmo usare onload , ma questo è spesso finnicky. Possiamo invece utilizzare alcuni trucchi CSS per forzare l'interazione dell'utente:

" onmouseenter="alert(1)" style="display:block;position:absolute;top:0;left:0;width:50000px;height:50000px;z-index:999999;

Questo diventa:

<input type="text" name="cn" size="20" maxlength="20" value="" onmouseenter="alert(1)" style="display:block;position:absolute;top:0;left:0;width:50000px;height:50000px;z-index:999999;">

Lo stile qui sembra un boccone ma è piuttosto semplice:

  • Rendi l'elemento visualizzato come elemento di blocco (così possiamo ridimensionarlo arbitrariamente)
  • Rendi la posizione dell'elemento assoluta all'interno della finestra (in modo che possiamo impostare la sua posizione ovunque)
  • Sposta l'elemento in (0,0)
  • Fai in modo che l'elemento riempia completamente la pagina (quindi il mouse dell'utente ha per inserirlo!)
  • Rendi l'elemento visualizzato sopra a tutto il resto.

Spero che questo spieghi come funziona tutto questo e come puoi passare dall'esempio fornito da ZAP a un exploit XSS funzionante.

    
risposta data 09.11.2018 - 02:39
fonte

Leggi altre domande sui tag