首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WordPress5.0 远程代码执行分析

WordPress5.0 远程代码执行分析

作者头像
信安之路
发布2019-03-12 10:46:35
1.2K0
发布2019-03-12 10:46:35
举报
文章被收录于专栏:信安之路信安之路

本文作者:七月火

2019年2月19日,RIPS 团队官方博客放出 WordPress5.0.0 RCE 漏洞详情,漏洞利用比较有趣,但其中多处细节部分并未放出,特别是其中利用到的 LFI 并未指明,之后网络上很多所谓的漏洞分析文章,多数对 LFI 并未分析,遂想一探究竟,并将自己的分析过程记录下来。

环境搭建

我们直接从 WordPress 官网下载 5.0 版本代码,搭建成功后先不要登录,因为从 3.7.0 版本开始, WordPress 在用户登录时,会在后台对小版本的改变进行更新,这样不利于我们分析代码。我们可以通过将 AUTOMATIC_UPDATER_DISABLED 设置成 true ,来禁止 WordPress 后台自动更新(在 wp-config.php 文件开头添加 define('AUTOMATIC_UPDATER_DISABLED', true); 即可)。

漏洞分析

路径穿越漏洞

该漏洞通过路径穿越和本地文件包含两个漏洞的组合,最终形成远程代码执行。我们先来看路径穿越问题。通过构造如下数据包,我们即可在数据库中插入一个恶意的路径:

上图中的 post 数据:

&action=editpost&meta_input[_wp_attached_file]=2019/03/demo.jpeg#/../../../../themes/twentynineteen/demo.jpeg

下面我们找到具体文件,审计代码。我们可以看到在 wp-admin/post.php 文件中,当 $action=editpost 的时候,会调用 edit_post 方法。在 edit_post 方法中,我们看到可控的 $post_data 变量,其数据来源于 $_POST ,紧接着将可控的 $post_data 变量传入 wp_update_post 方法,具体代码如下:

wp_update_post 方法中,我们看到其调用了 wp_insert_post 方法,该方法会将我们构造的恶意路径传入 update_post_meta 方法中,具体代码如下:

可以看到 update_post_meta 方法调用了 update_metadata 方法,而该方法调用了 wpdb 类的 update 方法,并将我们构造的恶意路径更新到数据库中。其具体代码如下:

更新前后, Mysql 中攻击者上传的图片对应的元信息变化如下:

至此,我们只是完成了将恶意路径插入数据库中,接下来我们还要让它发挥作用。在 WordPress 中,用户所上传的图片,会被保存至 wp-content/uploads/ 目录下。而程序获取图片时,有两种方法。第一种直接在 wp-content/uploads/ 目录下寻找;第二种则是在上一种方式无法获取图片时,从 http://localsite/wp-content/uploads/meta_value 下载,这里的 meta_value 就是上面我们可控的地方。

接着我们再把目标转移到 WordPress 的裁剪图片功能,通过该功能结合上面数据库中的可控的图片路径,我们即可实现将上传的图片移动到任意路径下。我们构造如下数据包:(这个数据包可以在保存裁剪好的图片时抓到,补上相应参数即可)

上图中的 post 数据:

_ajax_nonce=29a195c152&postid=28&do=save&action=crop-image&cropDetails[x1]=0&cropDetails[y1]=0&cropDetails[width]=1200&cropDetails[height]=1200&cropDetails[dst_width]=1200&cropDetails[dst_height]=1200&id=28

跟到具体的代码中,我们发现当 action=crop-image 时,程序会调用 wp_ajax_crop_image 方法对图片进行裁剪,具体代码如下:

wp_ajax_crop_image 方法中,根据 POST 中的 id 来校验 ajax 请求数据以及判断是否有权限编辑图片,然后将 $_POST['cropDetails'] 中的数据传入 wp_crop_image 方法,开始裁剪图片,具体代码如下:

接着我们就来到了漏洞的核心函数 wp_crop_image ,由上面的代码可知,传入该函数的参数均来源于 POST 数据,程序先根据 $_POST['id'] 从数据库中获取图片路径(下图 第5行 ),然后判断图片是否存在,不存在,则使用 URL 形式获取图片(下图 第8-9行 )。接着选择用于处理图片的拓展(下图 第16行 ),其中 Imagick 的优先级高于 GD ,然后开始裁剪。被裁剪的图片被命名为 'cropped-' . basename( $src_file ) ,然后为其创建目录(下图 第20-23行 ),最后调用 save 方法存入图片。

本地文件包含漏洞

分析完路径穿越漏洞,我们再来看看本地文件包含漏洞。由于 RIPS 官方对这个漏洞的描述一笔带过,我们便要自己来寻找。我们直接全局搜索 _wp_page_template 关键字,可以发现如下代码:

根据注释内容可知, get_page_template_slug 函数会根据传入的 $post 变量,从数据库中查询并返回其对应的模板文件名。而在 WordPress 程序运行最初,就会选择相应的模板文件名,并包含它,具体代码如下:

而且在查阅代码时,发现 get_single_template 函数和 get_page_template 函数都调用了 get_page_template_slug 函数。由于没有找到 get_page_template 函数的触发点,这里暂时值分析 get_single_template 函数。

为了触发该函数,我们需要先在添加多媒体文件处上传一个 txt 文件,然后和上面修改 _wp_attached_file 值类似,在更新文件信息处抓包并构造如下数据包:

上图中的 post 数据:

...&action=editpost&post_type=attachment&post_ID=8&save=Update&post_name=123&meta_input[_wp_page_template]=cropped-demo.jpeg

数据最终会调用 get_single_template 函数,并调用 get_page_template_slug 函数根据上面数据包中 post_ID 的值获取模板文件名(下图 第7行 ),接着调用 get_query_template 函数,并最终将模板文件名返回到 wp-includes/template-loader.php 文件中,然后 include 包含。

PS:上图的 load_template 方法其实也存在包含代码,但是这里没进入核心函数(没进入下图 第15行 ),其代码如下:

遇到的坑

如果没有开启、配置 Apacherewrite 模块,会导致上面的 LFI 失败(点击 查看附件页面 会直接 404),解决方法如下:

总结

最后用一张流程图来总结一下本次漏洞的触发过程吧,流程图如下:

参考

WordPress 5.0.0 Remote Code Execution:

https://blog.ripstech.com/2019/wordpress-image-remote-code-execution/

WordPress 5.0 RCE 详细分析:

https://paper.seebug.org/822/

Wordpress 5.0.0 远程代码执行漏洞分析与复现:

https://paper.seebug.org/825/

WordPress 如何获取页面对应的 page 模板 id 或者名称:

http://www.mr-fu.com/4101/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 信安之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 环境搭建
  • 漏洞分析
    • 路径穿越漏洞
      • 本地文件包含漏洞
      • 遇到的坑
      • 总结
      • 参考
      相关产品与服务
      网站建设
      网站建设(Website Design Service,WDS),是帮助您快速搭建企业网站的服务。通过自助模板建站工具及专业设计服务,无需了解代码技术,即可自由拖拽模块,可视化完成网站管理。全功能管理后台操作方便,一次更新,数据多端同步,省时省心。使用网站建设服务,您无需维持技术和设计师团队,即可快速实现网站上线,达到企业数字化转型的目的。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档