0x0 背景介绍
WordPress的Website Contact Form With File Upload插件在1.3.4及之前版本中,由于upload_file()函数缺少文件类型验证,存在任意文件上传漏洞。这使得未经身份验证的攻击者能够在受影响的网站服务器上上传任意文件,可能导致远程代码执行。
0x1 环境搭建
Ubuntu24+Docker搭建配置
#!/bin/bash
# WordPress 漏洞复现环境部署脚本(PHP 5.6 + Website Contact Form With File Upload 插件)
# 检查 unzip 是否安装,未安装则自动安装
if ! command -v unzip &> /dev/null; then
echo "📦 未检测到 unzip,正在安装..."
apt update && apt install -y unzip
echo "✅ unzip 安装完成"
fi
echo "🔧 阶段1/5:创建漏洞复现专用目录..."
mkdir -p vuln-wordpress && cd vuln-wordpress || { echo "❌ 创建目录失败"; exit 1; }
echo "✅ 工作目录: $(pwd)"
echo "📝 阶段2/5:生成 docker-compose.yml..."
cat > docker-compose.yml <<EOF
services:
db:
image: mysql:5.7
container_name: vuln-db
environment:
MYSQL_ROOT_PASSWORD: vuln-root-pass
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: vuln-user-pass
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 10
wordpress:
image: wordpress:php5.6-apache
container_name: vuln-wp
ports:
- "8081:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: vuln-user-pass
WORDPRESS_DB_NAME: wordpress
volumes:
- wp_data:/var/www/html/wp-content
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 15s
timeout: 10s
retries: 6
entrypoint: ["/bin/bash", "-c", "docker-entrypoint.sh apache2-foreground"]
volumes:
db_data:
wp_data:
EOF
echo "🚀 阶段3/5:启动漏洞复现环境..."
docker compose up -d
# 等待服务启动
echo "[*] 等待服务启动 (约60秒)..."
for i in {1..12}; do
echo -n "."
sleep 5
if [ $i -eq 6 ]; then
echo -ne " 50%"
fi
done
echo -e "\n[√] 服务启动完成!"
# 等待 WordPress 安装页面就绪
echo "[*] 等待服务完全就绪..."
until [ $(curl -s -w %{http_code} -o /dev/null http://localhost:8081/wp-admin/install.php) -eq 200 ]; do
echo -n "."
sleep 2
done
echo -e "\n[√] 服务已就绪"
echo "📦 阶段4/5:安装 Website Contact Form With File Upload 插件 (1.3.4)"
PLUGIN_URL="https://downloads.wordpress.org/plugin/website-contact-form-with-file-upload.1.3.4.zip"
PLUGIN_ZIP="website-contact-form-with-file-upload.1.3.4.zip"
PLUGIN_DIR="website-contact-form-with-file-upload"
# 删除旧插件目录(避免冲突)
rm -rf "$PLUGIN_DIR"
echo "⬇️ 下载插件..."
if ! wget -q "$PLUGIN_URL" -O "$PLUGIN_ZIP"; then
echo "⚠️ 下载失败,尝试备用镜像..."
if ! wget -q "https://mirror.ghproxy.com/$PLUGIN_URL" -O "$PLUGIN_ZIP"; then
echo "❌ 插件下载失败"
exit 1
fi
fi
echo "📦 解压插件..."
unzip -q "$PLUGIN_ZIP" -d "$PLUGIN_DIR"
echo "🚚 复制插件到容器..."
docker cp "$PLUGIN_DIR" vuln-wp:/var/www/html/wp-content/plugins/
echo "🧹 清理临时文件..."
rm -rf "$PLUGIN_DIR" "$PLUGIN_ZIP"
echo "🔍 验证插件是否安装成功..."
docker exec vuln-wp bash -c '
if [ -d "/var/www/html/wp-content/plugins/website-contact-form-with-file-upload" ]; then
echo "✅ 插件已成功复制"
else
echo "❌ 插件复制失败"
exit 1
fi'
echo "=============================================="
echo "✅ 漏洞复现环境部署完成!"
echo "▸ WordPress访问地址: http://localhost:8081"
echo "▸ 首次安装配置:"
echo "▸ 站点标题: WordPress_N-Media_CVE-2015-10137"
echo "▸ 用户: admin"
echo "▸ 密码: 默认强密码就可以"
echo "▸ 电子邮件:CVE-2015-10137@163.com"
echo
echo "▸ 登录后台启用插件: http://192.168.119.131:8081/wp-admin/plugins.php"
echo "▸ 手动启用N-Media Website Contact Form with File Uploader 插件"
# 执行环境部署脚本
chmod +x install.sh
./install.sh
# 关键输出
🔧 阶段1/5:创建漏洞复现专用目录...
📝 阶段2/5:生成 docker-compose.yml...
🚀 阶段3/5:启动漏洞复现环境...
📦 阶段4/5:安装插件...
🔄 重启容器使插件生效...
✅ 漏洞复现环境部署完成!
▸ WordPress访问地址: http://localhost:8081
0x2 漏洞复现
Xray-xpoc检测
https://gitee.com/songKl992/cve-series-update/blob/master/CVE/2025/CVE-2015-10137-wordpress.yml
复现截图

Python 自动化复现脚本
https://github.com/Kai-One001/-CVE-2015-10137-WordPress-N-Media-Website-Contact-Form-with-File-Upload-1.3.4
使用说明
python EXP.py -u http://192.168.63.131:8081/
复现截图

复现流量特征 (PACP)
1、未授权接口上传/wp-admin/admin-ajax.php?action=nm_webcontact_upload_file

2、明文执行一句话木马/wp-content/uploads/contact_files/1753327109-download.php

- 攻击请求特征:
- 端点:
POST /wp-admin/admin-ajax.php?action=upload_website_contact_file - Content-Type:
multipart/form-data - 文件名:
.php扩展名(如 exploit.php, shell.php) - 参数: 包含
Filedata字段
- 端点:
- 恶意文件访问:
- URL 模式:
/wp-content/uploads/website-contact-form-with-file-upload/{timestamp}-*\.php - 查询参数: 包含
?cmd=后跟系统命令
- URL 模式:
- 关键检测指标:
HTTP/1.1 200 OK+{"status":"uploaded", "filename":"XXX.php"}- 响应中包含
Content-Type: application/json - 后续对上传文件的直接访问请求
0x3 漏洞原理分析
漏洞位置
classes/plugin.class.php → upload_file() 方法
关键漏洞代码分析
function upload_file() {
// ... [设置和错误检查] ...
if (! empty ( $_FILES )) {
$tempFile = $_FILES ['Filedata'] ['tmp_name'];
$targetPath = $dirPath;
// 文件名处理:只过滤特殊字符但保留扩展名
$new_filename = strtotime ( "now" ) . '-' .
preg_replace ( "![^a-z0-9.]+!i", "_", $_FILES ['Filedata'] ['name'] );
$targetFile = rtrim ( $targetPath, '/' ) . '/' . $new_filename;
// 文件类型检查(仅限图片格式)
$type = strtolower ( substr ( strrchr ( $new_filename, '.' ), 1 ) );
// 直接移动上传文件 - 无内容验证!
if (move_uploaded_file ( $tempFile, $targetFile )) {
// 仅对图片创建缩略图
if (($type == "gif") || ($type == "jpeg") || ($type == "png") ||
($type == "pjpeg") || ($type == "jpg")) {
$this->create_thumb ( $targetPath, $new_filename, $thumb_size );
}
// 响应上传成功
$response ['status'] = 'uploaded';
$response ['filename'] = $new_filename;
}
// ... [错误处理] ...
}
// ... [响应输出] ...
}
漏洞根本原因
-
无文件内容验证:
- 仅基于文件扩展名判断文件类型
- 使用
move_uploaded_file()直接保存文件到服务器
-
脆弱的扩展名过滤:
preg_replace("![^a-z0-9.]+!i", "_", $_FILES['Filedata']['name'])- 允许保留
.php等危险扩展名 - 仅过滤特殊字符,但点号
.未被过滤
- 允许保留
-
危险的响应暴露:
- 直接返回上传文件路径:
{"filename":"1680000000-exploit.php"} - 泄露上传文件在服务器上的准确位置
- 直接返回上传文件路径:
-
无权限校验:
- 该端点可在未经认证的情况下直接访问
漏洞影响
- 攻击向量: 未认证文件上传 → 远程代码执行 (RCE)
- 影响范围: 安装该插件的所有 WordPress 网站 (v1.3.4及以下)
0x4 修复建议
修复方案
-
升级到最新版本:Thе Wеbѕitе Cоntасt Fоrm With Filе Uрlоаd 插件 fоr WоrdPrеѕѕ ≥ 1.3.4
-
临时防护措施
- 使用白名单验证文件扩展名和MIME类型
- 添加文件内容验证 (如使用
getimagesize()) - 设置文件大小限制
- 生成安全的随机文件名
免责声明:本文仅用于安全研究目的,未经授权不得用于非法渗透测试活动。
4065

被折叠的 条评论
为什么被折叠?



