Tracciamento dei tentativi XSS riflessi

1

Quindi, ecco un pezzo di codice che ho trovato.

<?php

    $name = $_GET['name'];

    if (!empty($name)) {
            $name = str_replace("<", "&lt;", $name);    //line 1
            $name = str_replace(">", "&gt;", $name);    //line 2
            $name = urldecode($name);                   //line 3

            echo $name;

    }

    ?>

Questo codice ho trovato in uno dei framework di pratica di hacking etico denominato bWAPP al livello di sicurezza 1. La soluzione potenziale per aggirare questa tecnica è a URL encode della stringa XSS due volte.

Supponiamo che la mia stringa XSS sia

<script>alert('XSS');</script>       //checkpoint alpha

Quindi codificarlo una volta dovrebbe darmi

%3Cscript%3Ealert%28%27XSS%27%29%3C%2fscript%3E  //checkpoint beta

PROBLEMA 1:
Se lo rintraccia, sulla linea 1 e 2 non succede niente. Ma sulla linea 3 viene decodificato. E così, la stringa risultante che ottengo diventa checkpoint alpha . Quindi, quando lo faccio eco, dovrei ricevere un avviso.

CONTRADICTION 1:
Non succede niente del genere e ho appena visualizzato checkpoint alpha in chiaro.

PROBLEMA 2: Quando, doppio codice, (che è la soluzione potenziale a questo problema), ottengo,

%253Cscript%253Ealert%2528%2527XSS%2527%2529%253C%252fscript%253E 

Ora, questa affermazione passa nuovamente attraverso le linee 1 e 2, e inciampando sulla linea 3, viene decodificata in checkpoint beta e viene ripresa.

CONTRADICTION 2:
Quando viene echeggiato, dovrei ottenere checkpoint beta in testo chiaro, ma improvvisamente il browser apre la finestra di avviso con XSS perfettamente funzionante.

Sono nuovo in questo campo e attualmente sto cercando di chiarire i miei concetti di base relativi allo sviluppo web. Per favore perdoni la mia formulazione errata. Grazie.

    
posta M.S.P 31.03.2017 - 11:29
fonte

2 risposte

3

Quando PHP recupera il parametro GET con $name = $_GET['name'] , esegue una decodifica implicita dell'URL. PHP non richiede di decodificare da sé un parametro URL.

Entrambi risultano nello stesso identico valore per $name :

http://yourapp/?name=<script>alert(1);</script>
http://yourapp/?name=%3Cscript%3Ealert%281%29%3C%2fscript%3E

Quindi anche se < assomiglia a %3c nel tuo URL, verrà memorizzato come% letterale% co_de in < . Di conseguenza, la parte $name riconosce correttamente str_replace() e < e filtra questi caratteri, impedendo in tal modo XSS.

La parte vulnerabile è il > esplicito alla fine.

Se fornisci l'URL urldecode() , la variabile http://yourapp/?name=%253c conterrà letteralmente $name (ovvero tre caratteri) e le funzioni %3c la ignoreranno perché né di str_replace() , % , 3 sembra una parentesi angolare. Quindi, alla fine, c esegue inutilmente un'altra decodifica e trasforma la sequenza urldecode() in un% co_de letterale dopo che ha già passato il filtro di sostituzione.

Se è ancora un po 'oscuro, sostituisci %3c con questo:

$name = urldecode('%253Cscript%253Ealert%25281%2529%253C%252fscript%253E')

Vedrai che questo ha lo stesso effetto di fornire la stringa come parametro URL e mostra che due urldecode sono ridondanti.

    
risposta data 31.03.2017 - 13:59
fonte
1

Ok quindi non sono uno sviluppatore PHP (o uno sviluppatore), ma l'ho provato.

tldr: $ _GET ['name'] urldecodes il nome del parametro

Ho usato il tuo codice ma ho inserito un:

echo $name;

Ad ogni riga.

Ho provato quanto segue:

  • < test & gt ;, il parametro $ name inizia come e finisce con caratteri di escape
  • % 3Ctest% 3E, il parametro $ name inizia come dopo $ _GET, quindi immediatamente il parametro è già urldecoded una volta
  • % 253Ctest% 253E, il parametro $ name inizia come% 3Ctest% 3E dopo $ _GET quindi viene decodificato una volta. Quindi la validazione fallisce e la seconda decodifica decodifica il parametro in

Per rispondere alle tue contraddizioni:

Contraddizione 1 esamina ciò che effettivamente ottieni usando firebug o un proxy o un http requester. Il tuo browser dice che ti mostra ma che cosa ha effettivamente ottenuto era < test > e l'ho interpretato a. Questo può essere fonte di confusione ma il browser ha recuperato la tua identità di fuga.

Contradiction 2 Beta è codificato una volta, viene decodificato una volta alla richiesta di avvio ($ _GET), quindi il < e > cambia in < e >.

    
risposta data 31.03.2017 - 12:27
fonte

Leggi altre domande sui tag