
Preuve de concept d'exploitation pour CVE-2026-11551, une vulnérabilité d'élévation de privilèges non authentifiée dans le plugin Branda White Label pour WordPress, permettant la prise de contrôle de compte via un double hachage de mot de passe.
White Label & Branding, Free Login Page Customizer <= 3.4.29 - Élévation de privilèges non authentifiée via prise de contrôle de compte
wp_update_user( $userdata )
│
├── wp_hash_password( $userdata['user_pass'] ) ← Line 2709: SUDAH DI-HASH
│
└── wp_insert_user( $userdata )
│
├── $user_pass = $userdata['user_pass'] ← Line 2228: HASHED
│
├── $data = compact('user_pass', ...) ← Line 2469: HASHED
│
├── apply_filters('wp_pre_inserter_id)
│ │
│ └── Branda: pre_insert_u
│ │
│ ├── query wp_sig['user_login']
│ ├── if meta['pas
│ │ $data['user_ta['password'])
│ │ ↑
│ ┌───
│ │
│ ↓
│ DOUBLE HASH: wp_d($raw))
│
└── $wpdb->update( $wpdb->users, $data, ... ) ← Line 2515: DOUBLE HASH TERSIMPAN
/**
* BRANDA - signup-password.php
* Filter: wp_pre_insert_user_data
*/
public function pre_insert_user_data( $data,
// ❌ TIDAK ADA CEK: if ($update) return
// ❌ Filter ini JALAN untuk INSERT DAN
if ( is_multisite() ) {
global $wpdb;
// ❌ $data['user_login'] dari POST n edit user
$query = $wpdb->prepare(
"SELECT meta FROM {$wpdb->signup
$data['user_login'] // ← bisa diubah attacker
);
$result = $wpdb->get_var( $query );
$meta = maybe_unserialize( $result
if ( is_array( $meta ) && isset( $me
// ❌ DOUBLE HASH: WordPress SUDAH hash sebelum filter ini jalan
// $meta['password'] = "mysecret
// wp_hash_password("mysecretpasama dari WP core)
// wp_hash_password("$P$Bxyz..."dari Branda)
$data['user_pass'] = wp_hash_pas
unset( $meta['password'] );
$wpdb->update(
$wpdb->signups,
array( 'meta' => maybe_seria
array( 'user_login' => $data
);
}
return $data;
}
// ...
}
// wp-includes/user.php:2706
if ( ! empty( $userdata['user_pass'] ) && $u_user_data->user_pass ) {
$plaintext_pass = $userdata['user
$userdata['user_pass'] = wp_hash_passwor // ← HASH #1
}
// wp-includes/user.php:2228 (UPDATE path)
$user_pass = ! empty( $userdata['user_pass'] $old_user_data->user_pass;
// $user_pass sekarang = "$P$Bxyz...SUDAH HASH"
// wp-includes/user.php:2505
$data = apply_filters( 'wp_pre_insert_user_dd, $userdata );
// Branda filter jalan, $data['user_pass'] SUDAH HASH dari line 2228
┌─────────────┬──────────────────────────┐
│ user_login │ meta (serialized) │
├─────────────┼──────────────────────────│
│ victim_user │ a:1:{s:8:"password";s:10:"H4cker123!"}│
└─────────────┴──────────────────────────┴
┌────────────────────────────────────────────┐
│ Field: username │
│ Value: victim_user ← DIUBAH │
└────────────────────────────────────────────┴
wp_update_user({ID: 2, user_login: "victim_user", ...})
│
├── user_pass = wp_hash_password(old_password) ← HASH #1
│
└── wp_insert_user({ID: 2, user_login: "victim_user", user_pass: "$P$Bhash1"})
│
└── apply_filters('wp_pre_insert_user_data', $data, true, 2)
│
└── Branda: pre_insert_user_data()
│
├── $data['user_login'] = "victim_user"
│
├── SELECT meta FROM wp_signups WHERE user_login = "victim_user"
│ → meta = 'a:1:{s:8:"password";s:10:"H4cker123!"}'
│
├── $meta['password'] = "H4cker123!"
│
└── $datword("H4cker123!")
← HASH #2 (DOUBLE!)
┌────┬────────────┬──────────────────────────────────┐
│ ID │ user_login │ user_pass │
├────┼────────────┼──────────────────────────────────┼
│ 2 │ victim_user│ $P$Bhash2 ← DOUBLE HASH! │
└────┴────────────┴──────────────────────────────────┘
- Nom d'utilisateur : victim_user
- Mot de passe : H4cker123! mais HASHÉ 2 fois
- Échec de connexion ! → Verrouillage du compte
- Se connecter avec les identifiants de l'inscription si la meta n'a pas encore été nettoyée
- Ou refaire une inscription avec le même user_login