• WordPress REST API 内容注入漏洞


    1 WordPress REST API 内容注入漏洞

    1.1 摘要

    1.1.1 漏洞介绍

    • WordPress是一个以PHP和MySQL为平台的自由开源的博客软件和内容管理系统。在4.7.0版本后,REST API插件的功能被集成到WordPress中,由此也引发了一些安全性问题。
    • 近日,一个由REST API引起的影响WorePress4.7.0和4.7.1版本的漏洞被披露,该漏洞可以导致WordPress所有文章内容可以未经验证被查看,修改,删除,甚至创建新的文章,危害巨大。

    1.1.2 漏洞环境

    • 操作机:Kali Linux
    • 目标机:CentOS 6.5

    1.1.3 实验工具

    • Apache 2.4
    • PHP 7.0
    • WordPress 4.7.1

    1.2 漏洞复现

    • 在浏览器中打开WordPress主页,可以看到一篇标题为“Hello World!”的博客

    • 下载POC漏洞验证文件:title_wp_rest_api.py,在终端中打开
    • 输入命令curl 172.16.12.2 | grep entry-title。可以看到该WordPress程序存在一篇文章,文章标题为“Hello World!”。(注:curl是利用URL语法在命令行方式下工作的开源文件传输工具。它被广泛应用在Unix、多种Linux发行版中)
    • 尝试执行POC越权修改该文章内容,输入命令:python title_wp_rest_api.py http://172.16.12.2/ yuanxin回车即可执行。
    • 再次输入命令curl 172.16.12.2 | grep entry-title,可以看到该文章标题由"Hello World"修改成为"yuanxin", 漏洞利用成功。
    • 返回浏览器,刷新界面可以看到博客的标题已经成功被修改
    • 漏洞复现成功

    1.3 漏洞分析

    1.首先来说一下 Word Press REST API

    • 控制器:WP-API 中采用了控制器概念,为表示自愿端点的类提供了标准模式,所有资源端点都扩展 WP_REST_Controller 来保证其实现通用方法。
    • 五种请求:WP-API 还有这么几种请求(也可以想成是功能吧):HEAD GET POST PUT DELETE,以上表示HTTP客户端可能对资源执行的操作类型。
    • HTTP客户端:WordPress本身在 WP_HTTP 类和相关函数中提供了一个HTTP客户端。用于从另一个访问一个WordPress站点。
    • 资源:简单来说,就是文章,页面,评论等。WP-API 允许HTTP客户端对资源执行CRUD操作(创建,读取,更新,删除)
    • 路由:路由是用于访问端点的“名称”,在URL中使用(在非法情况下可控,就像这个漏洞一样)。例如,使用URL http://example.com/wp-json/wp/v2/posts/123 :

    2.知道了 WP-API 的路由信息以及其操作方式,可以根据其运行的思路来看一下具体实现的代码。我们看一下 /wp-includes/rest-api/endpoints/class-wp-rest-post-controller.php

    • 这里有几件事要注意。注册的路由被设计为用数字填充ID请求参数。例如,使用URL :http://example.com/wp-json/wp/v2/posts/1234 的ID参数将被设置为 1234,路由(route)是 wp/v2/posts/1234 ,不包括 wp-json ,因为 wp-json 是API本身的基本路径。 这个路由有三个端点: GET触发一个 get_item 方法,将post数据返回给客户端。 PUT触发一个 update_item 方法,使数据更新,并返回更新的发布数据。 DELETE触发 delete_item 方法,将现在删除的发布数据返回给客户端,静态追踪。
    • 注意到register_rest_route中对路由进行了正则限制:'/(?P<id>[d]+)',这种行为本身可以是防止攻击者伪造恶意ID值的好方法,但是可以发现 $_GET 和 $_POST 值优先于路由正则表达式生成的值:这使得攻击者可以发送请求,如:/wp-json/wp/v2/posts/1234?id==12345helloworld这将分配12345helloworld到ID参数。

    3.接下来在审查各个端点方法中,找到了 update_item 这个方法,及其权限检查方法 update_item_permissions_check

    • update_item_permissions_check方法将我们的字母数字ID值直接传递给get_post()函数。此函数通过检查帖子是否实际存在 以及我们的用户是否有权编辑此帖来验证请求。这是一种好奇的清理请求的方式。如果发送一个没有相应帖子的ID,可以通过权限检查,并允许继续执行对update_item方法的请求。

    • 那么是什么可能导致get_post()在找到一个不是不存在的I时失败 。它使用wp_posts中的get_instance()静态方法来抓取帖子。

    • 从代码中可以看出,对于不是全部由数字字符组成的输入,它基本上会失败。对于攻击者,这意味着WordPress(认为它是一个有足够特权编辑此帖的用户)将运行 update_item方法。

    • update_item方法中,有一个细节: WordPress将ID参数转换为一个整数,然后传递给get_post()函数,这导致了一个非常危险的情况,因为PHP做类型比较和转换的方式时,攻击者可以提交类似的请求 /wp-json/wp/v2/posts/1234?id==12345helloworld时,便是发起了对ID为1234的文章的请求。

    1.4 修复方案

    1.5 思考总结

    • 本实践实现了WordPress REST API 内容注入漏洞的复现,并对漏洞原理进行了详细的分析。乍一看,感觉这个洞并没有什么太大的影响,但是仔细想了一下,危害还是很大的:
      • 先不说WordPress页面执行php代码的各种插件,还有相当一部分的WordPress文章可以调用短代码的方式导致WordPress所有文章内容可以未经验证被查看,修改,删除,甚至创建新的文章,这是一个思路。
      • 另一个思路就是可以进行对原来文章中的指定超链接进行修改,从而进行钓鱼。
      • 还有一个思路,就是利用WordPress文章中解析html以及JavaScript文件包含的做法,辅助其他方法,进行攻击。
  • 相关阅读:
    spring对返回结果的拦截器
    mysql 8.0.15 的my.ini 配置
    利用apache 的PropertyUtilsBean 实现map和pojo相互转换
    给数字补0
    清空文件的内容 和 统计文件的大小的命令
    MySQL的replace函数的用法
    PHP Warning: Module 'modulename' already loaded in Unknown on line 0 的解决方法
    技术总监Sycx的故事
    编译PHP扩展的通用方法
    给大家推荐几本经典技术书籍
  • 原文地址:https://www.cnblogs.com/yx20145312/p/7019818.html
Copyright © 2020-2023  润新知