WordPress 4.9.6版本在内,产生的漏洞及解决方法
WordPress是网络上最受欢迎的CMS系统。在这篇文章中详细讲解了这个漏洞产生的威胁。
在撰写本文时,该漏洞仍然没有补丁可用。并且所有WordPress版本,包括当前的4.9.6版本在内,都面临这个漏洞的威胁。
要想利用下面讨论的这个漏洞,攻击者需要事先获得编辑和删除媒体文件的权限。
利用这个漏洞,攻击者能够删除WordPress安装的任何文件。之外,攻击者还可以利用任意文件删除功能绕过一些安全措施,继而在Web服务器上执行任意代码。
攻击者可以删除下列文件:
.htaccess:通常情况下,删除该文件不会有任何安全影响。但是,在某些情况下,.htaccess文件包含与安全相关的安全约束(例如,对某些文件夹的访问限制)。
index.php文件:通常情况下,一些空的index.php文件被放置到各个目录中,以防止相应目录中的内容被列出。删除这些文件后,攻击者就能够列出受该方法保护的目录中的所有文件。
wp-config.php:删除这个WordPress安装文件会在下次访问该网站时触发WordPress安装过程。这是因为wp-config.php包含数据库凭证,如果没有它,WordPress的就会采取尚未安装之前的操作。攻击者可以删除该文件,然后,使用为管理员帐户选择的凭据进行安装,最后在服务器上执行任意代码。
漏洞详情
将未经过滤的用户输入传递给文件删除函数时,就可能触发任意文件删除漏洞。对于PHP来说,当调用unlink()函数并且可能影响部分或整个参数$filename的用户输入没有进行适当的过滤时,就可能出现这种情况;其中,该参数表示表要删除的文件的路径。
在WordPress Core中,引发这个漏洞的代码位于wp-includes/post.php文件中:
[php]function wp_delete_attachment( $post_id, $force_delete = false ) {
⋮
$meta = wp_get_attachment_metadata( $post_id );
⋮
if ( ! empty($meta['thumb']) ) {
// Don't delete the thumb if another attachment uses it.
if (! $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $wpdb->esc_like( $meta['thumb'] ) . '%', $post_id)) ) {
$thumbfile = str_replace(basename($file), $meta['thumb'], $file);
/** This filter is documented in wp-includes/functions.php */
$thumbfile = apply_filters( 'wp_delete_file', $thumbfile );
@ unlink( path_join($uploadpath['basedir'], $thumbfile) );
}
}
⋮
}[/php]
在上面显示的wp_delete_attachement()函数中,$ meta ['thumb']的内容未经任何过滤处理就直接传递给unlink()调用了。
这段代码的用途是,在删除图像的同时,一起将其缩略图删掉。
在WordPress中,通过媒体管理器上传的图像将作为attachement类型的文章对待。值$meta ['thumb']是从数据库中检索的,在数据库中,它保存在表示图像的文章的自定义字段中。
因此,在从数据库检索后,到传递给关键函数unlink()期间,并没有对表示缩略图文件名的值进行任何过滤或检查。
如果该值在保存到数据库之前也没有经过任何过滤,或过滤不充分的话——我们将在下一个代码清单中看到这种情况——就可能出现一个两阶段的任意文件删除漏洞。
[php]/wp-admin/post.php ⋮ switch($action) { ⋮ case 'editattachment': check_admin_referer('update-post_' . $post_id); ⋮ // Update the thumbnail filename $newmeta = wp_get_attachment_metadata( $post_id, true ); $newmeta['thumb'] = $_POST['thumb']; wp_update_attachment_metadata( $post_id, $newmeta ); ⋮[/php]
后面的代码片段(位于/wp-admin/post.php中)展示了隶属于附件的缩略图的文件名是如何保存到数据库的。
用户输入从$_POST ['thumb']中取出后,直到通过wp_update_attachment_metadata()保存到数据库这段过程中,系统没有对这些内容进行适当的安全过滤,因此,也就无法确保该值的确为正在编辑的附件的缩略图。
此外,由于$_POST ['thumb']的值可以将任意文件的路径保存到WordPress上传目录相对路径中,所以当附件被删除时,该文件也会被删除,如前面的代码所展示的那样。
临时补丁
在撰写本文的时候,WordPress中的这个漏洞仍未得到修复。已经开发了一个临时补丁供大家使用。
通过将该补丁添加到当前使用的WordPress主题/子主题的functions.php文件中,就可以将该补丁集成到现有的WordPress程序中。
[php]add_filter( 'wp_update_attachment_metadata', 'rips_unlink_tempfix' ); function rips_unlink_tempfix( $data ) { if( isset($data['thumb']) ) { $data['thumb'] = basename($data['thumb']); } return $data; }[/php]
实际上,该补丁的工作原理就是,“钩住”wp_update_attachement_metadata()调用,对提供给thumb的数据进行安全过滤,确保其中不包含任何使路径遍历成为可能的内容,这样攻击者就无法删除与安全相关的文件了。
这里提供的补丁只是临时性的,主要用来防止用户收到恶意攻击。
0条评论