技术派 | 漏洞分析:WordPress 5.0 RCE(CVE-2019-6977)

wufei123 发布于 2024-10-25 阅读(4)

此漏洞通过路径遍历和本地文件包含漏洞的组合实现WorePress核心中的远程代码执行,据漏洞发布者ripstech透露,此漏洞已在WordPress核心中存在6年以上权限需求author及以上权限,相对来说,权限需求不算高,很多小型协作内容输出小社区诸如乐谱站会较为常用wordpress,而后给予普通作者。

author权限影响范围因WordPress 4.9.9和5.0.1其他安全补丁所致,文件包含漏洞仅有5.0.0单一版本可利用,而路径遍历漏洞仍可使用且当前仍未打补丁任何安装了此插件的WordPress站点都会错误地处理Post Meta条目,这样仍然可以进行利用。

漏洞基础将图像上传到WordPress安装时,首先将其移动到uploads目录(wp-content/uploads)WordPress还将创建对数据库中图像的内部引用,以跟踪元信息,例如图像的所有者或上传的时间。

该属性作为Post Meta条目存储在数据库中这些条目中的每一个都是键/值对,分配给某个ID譬如:SELECT * FROM wp_postmeta WHERE post_ID = 50; +---------+-------------------------+----------------------------+ | post_id | meta_key | meta_value | +---------+-------------------------+----------------------------+ | 50 | _wp_attached_file | evil.jpg | | 50 | _wp_attachment_metadata | a:5:{s:5:"width";i:450 ... | ... +---------+-------------------------+----------------------------+。

在此示例中,图像已分配给post_ID 50.倘若用户希望将来使用或编辑具有所述ID的图像,WordPress将查找匹配的_wp_attached_file条目并使用它的值以便在wp-content/uploads

目录中查找该文件漏洞构成本地文件包含部分WordPress 4.9.9和5.0.1之前的这些Post Meta条目的问题在于可以修改任何条目并将它们设置为任意值当图像被更新时(例如,它的描述被改变),该。

edit_post()函数被调用该函数直接作用于$_POST数组function edit_post( $post_data = null ) { if ( empty($postarr) ) $postarr = &$_POST; ⋮ if ( ! empty( $postarr[meta_input] ) ) { foreach ( $postarr[meta_input] as $field => $value ) { update_post_meta( $post_ID, $field, $value ); } }。

可以看出,可以注入任意Post Meta条目由于未对哪些条目进行了修改,因此攻击者可以更新_wp_attached_file元条目并将其设置为任何值这不会以任何方式重命名文件,它只会更改WordPress在尝试编辑图像时要查找的文件。

这将导致稍后的路径遍历具体位置:POST参数_wp_page_template在函数get_page_template_slug()中的文件wordpress / wp-includes / post-template.php

的第1695行中被接收。

用户提供的数据在函数locate_template()中的文件wordpress / wp-includes / template.php的第635行连接成路径标记。

然后,在函数load_template()中的文件wordpress / wp-includes / template.php的第690行中的敏感操作require()中使用用户提供的数据进行未经过处理。

路径遍历部分路径遍历发生在wp_crop_image()用户裁剪图像时调用的函数中该函数将图像的ID带到crop($attachment_id)并从数据库中获取相应的_wp_attached_filePost Meta条目。

由于缺陷edit_post(),$src_file可以设置为任何东西function wp_crop_image( $attachment_id, $src_x, ...) { $src_file = $file = get_post_meta( $attachment_id, _wp_attached_file ); ⋮。

在下一步中,WordPress必须确保图像实际存在并加载它WordPress有两种加载给定图像的方法第一种是简单地查找目录中_wp_attached_file Post Meta条目提供的文件名wp-content/uploads。

(下一个代码片段的第2行)如果该方法失败,WordPress将尝试从其自己的服务器下载图像作为后备为此,它将生成一个下载URL,该URL包含wp-content/uploads目录的URL和存储在_wp_attached_file

Post Meta条目中的文件名(第6行)举一个具体的例子:如果存储在_wp_attached_file Post Meta条目中的值是evil.jpg,那么WordPress将首先尝试检查文件是否wp-content/uploads/evil.jpg

存在如果没有,它会尝试从以下URL下载文件:https://targetserver.com/wp-content/uploads/evil.jpg尝试下载图像而不是在本地查找图像的原因是某些插件在访问URL时动态生成图像。

但是,这里没有进行任何过滤WordPress将简单地将上传目录和URL与$src_file用户输入连接起来一旦WordPress成功加载了有效图像wp_get_image_editor(),即裁剪图像 ⋮ if ( ! file_exists( "wp-content/uploads/" . $src_file ) ) { // If the file doesnt exist, attempt a URL fopen on the src link. // This can occur with certain file replication plugins. $uploads = wp_get_upload_dir(); $src = $uploads[baseurl] . "/" . $src_file; } else { $src = "wp-content/uploads/" . $src_file; } $editor = wp_get_image_editor( $src ); ⋮

将裁剪后的图像保存回文件系统(无论是否下载)生成的文件名将是$src_file由get_post_meta()攻击者控制的返回文件对结果文件名字符串进行的唯一修改是文件的基本名称前缀cropped-(下一个代码片段的第4行)。

为了遵循示例evil.jpg,生成的文件名将是cropped-evil.jpg然后,WordPress通过wp_mkdir_p()(第6行)在结果路径中创建不存在的任何目录使用save()图像编辑器对象的方法将其最终写入文件系统。

该save()方法还不对给定的文件名执行路径遍历检查 ⋮ $src = $editor->crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs ); $dst_file = str_replace( basename( $src_file ), cropped- . basename( $src_file ), $src_file ); wp_mkdir_p( dirname( $dst_file ) ); $result = $editor->save( $dst_file );。

函数整体(wp-admin / includes / image.php)如是:

实现RCE综上,可以确定哪个文件被加载到图像编辑器中(因未进行处理)但是,如果文件不是有效图像,图像编辑器将会抛出异常故而,只能在上传目录之外裁剪图像那么如果未找到所需图像,WordPress会尝试下载,这就导致了RCE。

设置_wp_attached_file为evil.jpg?shell.php,这将导致对以下URL发出HTTP请求:https://targetserver.com/wp-content/uploads/evil.jpg?shell.php

此请求将返回有效的图像文件,因为?在此上下文中忽略了所有内容生成的文件名将是evil.jpg?shell.php虽说save()图像编辑器的方法不会检查是否存在路径遍历,但它会将正在加载的图像的mime类型的扩展名附加到生成的文件名中。

在这种情况下,结果文件名将是evil.jpg?cropped-shell.php.jpg这使得新创建的文件再次无害但是,仍可以通过使用诸如的Payload将生成的图像植入任何目录evil.jpg?/../../evil.jpg。

路径遍历 –> themes目录 LFI每个WordPress主题只是一个位于WordPress目录中的wp-content/themes目录,并为不同的案例提供模板文件例如,如果博客的访问者想要查看博客帖子,则WordPress会。

post.php在当前活动主题的目录中查找文件如果它找到了模板,那include()就是它为了添加额外的自定义层,可以为某些帖子选择自定义模板为此,用户必须将数据库中的_wp_page_template。

Post Meta条目设置为这样的自定义文件名这里唯一的限制是要include()编辑的文件必须位于当前活动主题的目录中通常,无法访问此目录,也无法上载文件但是,通过滥用上述Path Traversal,可以将恶意制作的图像植入当前使用的主题的目录中。

然后攻击者可以创建一个新帖子并滥用相同的错误,使他能够更新_wp_attached_file Post Meta条目以便include()映像通过将PHP代码注入映像,攻击者可以获得任意远程执行代码Payload制作—-Imagick

WordPress支持PHP的两个图像编辑扩展:GD(https://libgd.github.io/)和Imagick(https://www.imagemagick.org/)它们之间的区别在于Imagick不会删除图像的exif元数据,其中可以存储PHP代码。

总结WordPress 5.0.0 RCE 条件较为苛刻,但毕竟是RCE,一旦被利用危害巨大况且,虽说仅这一小版本的本地文件包含可协同目录遍历完成RCE,但因为这目录遍历漏洞至今未修,一旦用户安装允许覆盖任何Post data的插件,这RCE依然可被利用。

参考https://blog.ripstech.com/2019/wordpress-image-remote-code-execution/https://wordpress.org/download/

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-6977

往期精彩内容呈现新闻派 | 新春寄语 | 知否?知否?安全防御应该省心可靠新闻派 | 丁牛科技成功入围2019 BCTF总决赛并受邀发表了主题演讲新闻派 | 2018中国区块链企业百强榜新鲜出炉,丁牛科技成功入选

技术派 | 简单高效的模糊测试——Fuzzing技术派 | 漏洞挖掘、利用及修复——从人工到自动的跨越新闻派 | 丁牛科技作为核心贡献单位,参与撰写《区块链安全白皮书》新闻派 | 2019年区块链更大规模应用成为集体共识

“递送原汁网安干货分享最新网安成果

长按识别二维码,关注丁牛科技

亲爱的读者们,感谢您花时间阅读本文。如果您对本文有任何疑问或建议,请随时联系我。我非常乐意与您交流。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。