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

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

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

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

工具目录

分类

查看所有分类
Loading categories
CVE-2025-11262-Lab — # 用于复现 CVE-2025-11262 的 Docker 实验环境 CVE-2025-11262 是 Link Whisper Free WordPress 插件中存在的一个未认证存储型盲 XSS 漏洞。本实验环境包含存在漏洞的目标与已修复的目标、PoC 脚本以及根因分析。 | Kitploit
工具/GitHubGitHub/rootdirective-sec/cve-2025-11262-lab
漏洞分析Web应用程序漏洞利用CTF渗透测试学习与教育实验室与实践
GitHubrootdirective-sec/cve-2025-11262-lab

CVE-2025-11262-Lab

# 用于复现 CVE-2025-11262 的 Docker 实验环境 CVE-2025-11262 是 Link Whisper Free WordPress 插件中存在的一个未认证存储型盲 XSS 漏洞。本实验环境包含存在漏洞的目标与已修复的目标、PoC 脚本以及根因分析。

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
查看仓库
623个月前尚未审核
分享

CVE-2025-11262 - Link Whisper Free 未认证存储型盲 XSS

执行摘要

此仓库包含一个本地 Docker 实验环境,用于复现 CVE-2025-11262,这是一个影响 WordPress 插件 Link Whisper Free 的未认证存储型跨站脚本漏洞。

该实验环境对比两个插件版本:

ServicePlugin versionPurposeURL
vuln0.9.0易受攻击的目标http://127.0.0.1:8081
patched0.9.1已修补的对比目标http://127.0.0.1:8082

所演示的漏洞链条如下:

Unauthenticated REST request
→ attacker-controlled user_id is persisted
→ a privileged WordPress user opens the Link Whisper AI Subscription page
→ the stored value is rendered into an admin JavaScript context
→ alert("CVE-2025-11262-LAB") executes on the vulnerable version

攻击者无需登录即可植入存储型 payload。当特权 WordPress 用户打开受影响的 admin 页面时,JavaScript 才会执行。

本实验环境仅用于受控的本地研究、源码级理解和作品集展示。

已验证事实

声明证据如何在本实验环境中验证
Link Whisper Free 0.9.0 存在漏洞。公开公告确认,Link Whisper Free 版本直至并包括 0.9.0 均受影响。对 http://127.0.0.1:8081 运行 PoC,然后打开打印出的 admin URL。
Link Whisper Free 0.9.1 包含修复。公开公告和变更日志数据将 0.9.1 标识为已修补版本。对 http://127.0.0.1:8082 运行相同的 PoC;不应出现 alert。
payload 植入无需认证。PoC 发送 POST 请求,不附带 WordPress cookie、登录状态或 nonce。查看 poc/poc.py;它只需要 --url。
可见影响在 WordPress 管理区域触发。当特权用户打开 Link Whisper AI Subscription 页面时,存储的值会被渲染。运行 PoC 后,以管理员身份登录并打开打印出的 admin URL。
已修补的目标在 HTTP 层可能仍返回 "ok"。本地测试显示,两个目标都可能返回 "ok";有意义的区别在于 payload 是否被持久化并执行。比较浏览器在 8081 和 8082 上的行为。

以下是 Root Cause Summary 部分,可直接替换到 README 中。该部分为 public-safe,不涉及 vuln_detail.txt 等内部文件,基于你当前使用的 lab/source。

根本原因摘要

CVE-2025-11262 由 Link Whisper Free 0.9.0 中的存储型 JavaScript 注入链导致。

该问题并非单一缺失转义调用,而是多个不安全行为组成的链条:

Unauthenticated REST endpoint
→ insufficient validation of user_id
→ persistent storage in wpil_ai_access_user_id
→ unsafe rendering into an admin JavaScript context
→ stored XSS when a privileged user opens the AI Subscription page

未认证的 REST 端点

Link Whisper Free 在插件 REST 命名空间下注册了一个 AI 认证 REST 端点:

const REST_SLUG = 'link-whisper';
const AI_AUTH = 'ai-auth';

该端点被注册为 POST 路由:

register_rest_route(self::REST_SLUG, self::AI_AUTH, [
    'methods'             => 'POST',
    'callback'            => [
        $this,
        'ai_auth_handler'
    ],
    'permission_callback' => "__return_true",
    'show_in_index'       => false
]);

由于权限回调为 __return_true,该端点无需认证即可访问。

在实验环境中,实际生效的端点为:

/wp-json/link-whisper/ai-auth

这意味着未认证的攻击者无需 WordPress 会话、nonce 或管理员账户,即可向该端点发送请求。

0.9.0 中易受攻击的输入处理

在 Link Whisper Free 0.9.0 中,处理器从 REST 请求中读取攻击者可控的参数:

public function ai_auth_handler( WP_REST_Request $request )
{
    if(!empty($request->get_param('access_token'))){
        $token = $request->get_param('access_token');
        $user_id = $request->get_param('user_id');
        $uid = (int)$request->get_param('uid');
        $uemail = $request->get_param('uemail');

        if(!empty($token) && false !== strpos($token, 'ai-')){
            update_option('wpil_ai_access_token', Wpil_Toolbox::encrypt($token));
            update_option('wpil_ai_access_user_id', $user_id);
            update_option('wpil_ai_access_user_email', $uemail);
            update_user_meta($uid, 'wpil_ai_access_user_id', $user_id);
            update_user_meta($uid, 'wpil_ai_access_user_email', $uemail);
            update_option('wpil_ai_access_authorized', true);
        }

        return 'ok';
    }

    return new WP_Error(400, 'Bad request', [ 'status' => 404 ]);
}

易受攻击的行为在于薄弱验证条件:

if(!empty($token) && false !== strpos($token, 'ai-')){

该条件仅检查所提供 access token 是否包含字符串 ai-。

在存储 user_id 之前,没有严格的验证:

update_option('wpil_ai_access_user_id', $user_id);

因此,攻击者控制的 JavaScript 可被持久化到 WordPress options 表中。

持久化存储

攻击者控制的 user_id 值被存储在 WordPress option 中:

wpil_ai_access_user_id

在本实验环境中,PoC 发送以下仅限本地的 payload:

</script><script>alert("CVE-2025-11262-LAB")</script>

在易受攻击的服务上,payload 被存储为 wpil_ai_access_user_id 的值。

攻击者无需登录即可植入 payload。payload 通过未认证的 REST 端点植入。

管理员 JavaScript 汇聚点

该存储的值随后通过插件设置逻辑读取:

public static function get_linkwhisper_ai_user_id(){
    return get_option('wpil_ai_access_user_id', '');
}

该值被赋给 $ai_id,并渲染到 AI Subscription 管理页面中。

在 Link Whisper Free 0.9.0 中,该值被直接插入到 JavaScript 字符串中:

body: JSON.stringify({
    ai_id: "<?php echo $ai_id;?>",
    subscription_id: "<?php echo ((!empty($sub)) && isset($sub->subscription_id)) ? $sub->subscription_id: null;?>"
})

由于 $ai_id 在插入到 JavaScript 上下文之前未被转义,存储型 payload 可以突破预期字符串,并在打开管理页面时执行 JavaScript。

使用实验环境中的 payload 时,易受攻击的渲染输出等效于:

body: JSON.stringify({
    ai_id: "</script><script>alert("CVE-2025-11262-LAB")</script>",
    subscription_id: ""
})

在浏览器中,注入的闭合 </script> 标签终止原始脚本块,然后注入的 <script> 块执行。

触发条件

payload 由未认证攻击者植入,但执行需要一个特权 WordPress 用户打开受影响的 admin 页面:

/wp-admin/admin.php?page=link_whisper_ai_subscription

在本实验环境中,以 WordPress 管理员身份打开受影响页面,以触发 alert 对话框。

这使得该问题成为针对已认证 WordPress 管理员或可访问 Link Whisper AI Subscription 管理页面的特权用户的未认证存储型 XSS。

0.9.1 中的补丁行为

Link Whisper Free 0.9.1 在存储 AI 认证值之前增加了更严格的验证。

修补后的处理器要求 token 和 user ID 符合严格格式:

if(
    !empty($token) &&
    false !== strpos($token, 'ai-') &&
    (bool) preg_match('/\Aai-[0-9a-f]{64}\z/i', $token) &&
    (bool) preg_match('/\A[0-9a-f]{32}\z/i', $user_id)
){
    update_option('wpil_ai_access_token', Wpil_Toolbox::encrypt($token));
    update_option('wpil_ai_access_user_id', $user_id);
    update_option('wpil_ai_access_user_email', sanitize_email($uemail));
    update_option('wpil_ai_access_authorized', true);
}

为 user_id 添加的重要验证是:

preg_match('/\A[0-9a-f]{32}\z/i', $user_id)

这可以防止任意 JavaScript 被存储为 AI user ID。

0.9.1 版本还在将值渲染到 JavaScript 上下文之前对其进行转义:

body: JSON.stringify({
    ai_id: "<?php echo esc_attr($ai_id);?>",
    subscription_id: "<?php echo ((!empty($sub)) && isset($sub->subscription_id)) ? esc_attr($sub->subscription_id): '';?>"
})

因此,该补丁从两个层面缓解了此问题:

Input validation before persistence
Output escaping before JavaScript rendering

实验环境确认的行为

该实验环境确认了 0.9.0 与 0.9.1 之间的差异。

在 Link Whisper Free 0.9.0 上:

POST /wp-json/link-whisper/ai-auth
→ returns "ok"
→ stores the payload in wpil_ai_access_user_id
→ opening the AI Subscription admin page triggers alert("CVE-2025-11262-LAB")

在 Link Whisper Free 0.9.1 上:

POST /wp-json/link-whisper/ai-auth
→ may still return "ok"
→ does not store the payload
→ opening the AI Subscription admin page does not trigger an alert

仅凭 HTTP 响应不足以判断目标是否易受攻击,因为两个版本都可能返回 "ok"。有意义的行为差异在于 payload 是否被持久化并随后在管理员 JavaScript 上下文中渲染。

实验环境架构

该实验环境通过 Docker Compose 运行两个隔离的 WordPress 实例和两个独立的 MySQL 数据库。

.
├── docker/
│   └── lab-entrypoint.sh
├── docker-compose.yml
├── patched/
│   └── Dockerfile
├── poc/
│   └── poc.py
├── README.md
└── vuln/
    └── Dockerfile

Docker 入口点会自动:

  • 等待 WordPress 和数据库就绪,
  • 在需要时安装 WordPress,
  • 激活 Link Whisper Free,
  • 准备复现所需的管理页面,
  • 打印实验环境的登录信息。

两个服务的默认 WordPress 管理员凭据:

admin / AdminPassw0rd!

环境要求

  • Docker Desktop 或 Docker Engine
  • Docker Compose v2
  • Python 3
  • 构建镜像期间需要联网,因为 Dockerfile 会从 WordPress.org 下载插件包

快速开始

构建并启动实验环境:

docker compose down -v
docker compose build --no-cache
docker compose up -d

检查容器:

docker compose ps

预期暴露的服务:

Vulnerable target: http://127.0.0.1:8081
Patched target:    http://127.0.0.1:8082

你还可以查看设置日志:

docker compose logs vuln patched

设置成功后,每个 WordPress 实例中应显示 Link Whisper 为已激活状态。

PoC 使用方法

对易受攻击的服务运行 PoC:

python3 poc/poc.py --url http://127.0.0.1:8081

PoC 通过未认证的 REST 端点发送以下仅限本地的 payload:

</script><script>alert("CVE-2025-11262-LAB")</script>

脚本运行后,在浏览器中打开打印出的 admin URL,并使用以下信息登录:

admin / AdminPassw0rd!

在易受攻击的服务上,浏览器应显示包含以下内容的 alert:

CVE-2025-11262-LAB

为了对比,对已修补的服务运行相同的 PoC:

python3 poc/poc.py --url http://127.0.0.1:8082

然后打开打印出的已修补服务的 admin URL。不应触发任何 alert。

下载工具