Sfruttare PHP tramite i parametri GET

9

Per essere chiari, questo è nell'interesse dei test etici per proteggere un'applicazione per conto del mio lavoro.

Ora che è fuori mano, ecco i dettagli:

  1. I parametri GET non sanificati vengono utilizzati in uno script PHP per modificare dinamicamente una pagina HTML.
  2. Solo la sottostringa param prima di / viene scritta nel file HTML

Sto cercando di eseguire il codice <?php phpinfo() ?> quando viene eseguita la pagina HTML.

Quando cerco:

[host]/index.php/someparam=<?php phpinfo() ?>

L'origine della pagina mostra che il codice è stato inserito in un commento:

<!--?php phpinfo() ?-->

Il codice viene solo racchiuso in un commento html quando viene rilevato <? , vale a dire ?> a sé stante.

Qualche idea su come sconfiggerlo? Ho provato:

%3C%3F%70%68%70%20%70%68%70%69%6E%66%6F%28%29%20%3F%3E

che risulta ancora in:

<!--?php phpinfo() ?-->

base64 esegue solo rendering così come sono e non viene trattato come codice, i valori decimali non sono presenti da nessuna parte nell'origine (nemmeno avvolti in un commento html).

    
posta Très 28.05.2013 - 06:32
fonte

2 risposte

9

Lo scenario semplicistico sarebbe provare a inviare --><?php phpinfo();?><!-- . Se il tag <?php è sfuggito, questo risulterebbe in

 <!-- -->
 <?php phpinfo();
 <!-- -->

(newlines aggiunti per chiarezza). Ma la presenza di <?php ...?> nella pagina HTML potrebbe non essere sufficiente; il codice PHP deve essere interpretato lato server, non solo restituito al client.

Esaminando più da vicino l'inizio della stringa risultante:

 <!--?

è chiaro che non è il tag PHP, ma solo il < che attiva l'escape, e probabilmente è inteso come una difesa HTML / XML / XSS. Ciò significa che non puoi inviare contenuti attivi e farli eseguire, o renderizzati in forma eseguibile dal client.

Anche in questo caso potresti provare con "pre-unescaping", inviando

 < --><hr><!-- >

e vedere se questo viene trasformato ingenuamente in

 <!----><hr><!-- -->

che dovrebbe essere visualizzato come HTML, o che è più completamente definito in

 <!-- -- --><!-- hr --><!-- !-- -->

che non rende nulla utile. Questo dipende completamente da come viene effettuato il rilevamento dei tag aperti HTML e da come funziona. A volte preg_replace viene utilizzato con espressioni regolari non corrette, incomplete o non-golose, che possono defangare solo il primo o l'ultimo tag o deframmentare ciecamente la prima apertura con l'ultima chiusura, ignorando le bugie nel mezzo. In questo caso, la pagina è vulnerabile all'iniezione di Javascript e a una serie di attacchi correlati.

Il codice sanitizzante è disponibile per l'ispezione?

Esempio di convalida ingenua

Ad esempio, questo codice apparentemente sanifica l'output HTML.

preg_replace("/<(.*)>/", "<!-- \1 -->", $input);

ma (a parte essere una misura mal concepita) la mancanza dell'operatore ungreedy? lo rende vulnerabile a un semplice attacco pre-non inescusabile:

<?php
    $params = array(
            "<script>alert('FAIL');</script>",
            "< --><script>alert('Success');</script><!-- >",
    );
    foreach($params as $param)
            print preg_replace("/<(.*)>/", "<!-- \1 -->", $param) . "\n\n\n";
?>

provoca il fallimento del primo attacco naive, mentre il secondo ha esito positivo:

<!-- script>alert('FAIL');</script -->

<!--  --><script>alert('Success');</script><!--  -->

Sfortunatamente, questa opzione preg_replace è spesso suggerita o implementata come una "soluzione rapida" per gli attacchi di HTML injection e, poiché la maggior parte delle "correzioni temporanee" sono solite fare, potrebbe diventare permanente .

Una strategia migliore sarebbe quella di filtrare out tutto ciò che non appartiene al parametro originale (ad es. sostituire [^A-Za-z0-9_] con niente), o pensare che la presenza di caratteri proibiti significhi che qualcosa di malvagio in questo modo viene , e quindi la reazione più sicura è eliminare la richiesta (magari informando l'utente, in caso di casualità o incidente un problema, ad esempio un link sintatticamente scorretto, da qualche altra parte, per cui è altamente raccomandato il logging di HTTP_REFERER .

    
risposta data 28.05.2013 - 09:00
fonte
2

Considerando questo, l'unica cosa che posso pensare è un attacco XSS . Quello che stai tentando molto probabilmente fallirà, non perché il sito sta filtrando determinati input, è solo il modo in cui questa "funzionalità" è implementata. Molto probabilmente è qualcosa del genere:

echo '<!--'.$_GET['someparam'].'-->';

Anche senza <!-- --> , ciò che lo script sta facendo è prendere il tuo input, archiviarlo in una variabile, quindi restituirlo a te, non viene elaborato nuovamente dall'interprete di PHP.

Una situazione sfruttabile sarebbe eval($_GET); , ma chiaramente non è il caso qui.

    
risposta data 28.05.2013 - 08:36
fonte

Leggi altre domande sui tag