Wordpress内容注入漏洞致超67000个网站遭黑产利用

如果你的网站使用的是WordPress,并且没有及时更新官方上周发布的补丁,升级到v4.7.2版本,那么你的网站很有可能受到这4个黑客组织的攻击。

据国外Web安全公司Sucuri表示,自上周一该漏洞细节公开后,攻击范围不断扩大,最近每天趋于3000次。

随着时间的推移利用REST API漏洞尝试次数(来源:Sucuri)

攻击者正在利用WordPress的REST API的漏洞,该漏洞由WordPress团队两个星期前修复并更新补丁,他们于上周一公开了漏洞详情。

攻击者利用这个漏洞精心构造一个向目标站点REST API发起的HTTP请求,可以修改文章的标题和内容。

上周已经有人提供了完整的利用代码。

超过67,000的网站内容已经被篡改

即使该漏洞仅影响WordPress4.7.0和4.7.1两个版本而且该CMS内置有自动更新的功能,但仍然有很多网站没有更新。

据Sucuri部署的蜜罐服务器收集到的数据显示,在过去的一周,有四波攻击者正在着手利用这个漏洞。

由于攻击已经持续一段时间了,谷歌已经可以检索一部分被攻击的内容。

通过Google检索被篡改的站点

通过Google搜索"by w4l3XzY3",可以浏览一些受影响的站点。

部分受影响的站点列表

更多受影响站点可在http://www.zone-h.org/archive/notifier=w4l3XzY3/page=1查看。

目前,使用REST API漏洞篡改网站的这些组织只是做了一些知名度的曝光,将网站内文章的标题和正文修改为自己的内容。

其中一个被篡改的站点

Sucuri's CTO, Daniel Cid表示希望看到更专业的内容进入大家的视野,如利用该漏洞发布更复杂的内容,黑链SEO:如插入链接和图像。

利用漏洞做这种篡改的话,做黑链SEO,可以提高其他网站的搜索引擎排名,或者宣传一些其他的非法产品。

当然如果网站内容被篡改为一些恶意内容,会导致网站被搜索引擎屏蔽。

建议所有使用WordPress的网站主及时更新至最新版本v4.7.2。避免由于REST API的安全问题,导致网站被搜索引擎屏蔽。

原文链接:https://www.bleepingcomputer.com/news/security/over-67-000-websites-defaced-via-recently-patched-wordpress-bug/

0x00 漏洞简述

1. 漏洞简介

在REST API自动包含在Wordpress4.7以上的版本,WordPress REST
API提供了一组易于使用的HTTP端点,可以使用户以简单的JSON格式访问网站的数据,包括用户,帖子,分类等。检索或更新数据与发送HTTP请求一样简单。上周,一个由REST

API引起的影响WorePress4.7.0和4.7.1版本的漏洞被披露,该漏洞可以导致WordPress所有文章内容可以未经验证被查看,修改,删除,甚至创建新的文章,危害巨大。

2. 漏洞影响版本

WordPress4.7.0

WordPress4.7.1

0x01 漏洞复现

Seebug上已经给出详细的复现过程,在复现过程中可以使用已经放出的POC来进行测试。

0x02 漏洞分析

其实漏洞发现者已经给出了较为详细的分析过程,接下来说说自己在参考了上面的分析后的一点想法。

WP REST API

首先来说一下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操作(创建,读取,更新,删除,这边只展示和漏洞相关的部分):

GET /wp-json/wp/v2/posts获取帖子的集合:

GET /wp-json/wp/v2/posts/1获取一个ID为1的单独的Post:

可以看到ID为1的文章标题为Hello World,包括文章的路由也有。

路由

路由是用于访问端点的“名称”,在URL中使用(在非法情况下可控,就像这个漏洞一样)。

例如,使用URLhttp://example.com/wp-json/wp/v2/posts/123:

路由(route)是wp/v2/posts/123,不包括wp-json,因为wp-json是API本身的基本路径。

这个路由有三个端点:

GET触发一个get_item方法,将post数据返回给客户端。

PUT触发一个update_item方法,使数据更新,并返回更新的发布数据。

DELETE触发delete_item方法,将现在删除的发布数据返回给客户端。

静态追踪

知道了WP-API的路由信息以及其操作方式,可以根据其运行的思路来看一下具体实现的代码。

我们看一下/wp-includes/rest-api/endpoints/class-wp-rest-post-controller.php:

根据上面的信息,我们可以知道这是注册controller对象的路由,实现路由中端点方法。

在这里,如果我们向/wp-json/wp/v2/posts/1发送请求,则ID参数将被设置为1:

同时,注意一下这里:


  1. register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(   
  2.             array( 
  3.                 'methods'             => WP_REST_Server::READABLE, 
  4.                 'callback'            => array( $this, 'get_item' ), 
  5.                 'permission_callback' => array( $this, 'get_item_permissions_check' ), 
  6.                 'args'                => $get_item_args, 
  7.             ), 
  8.             array( 
  9.                 'methods'             => WP_REST_Server::EDITABLE, 
  10.                 'callback'            => array( $this, 'update_item' ), 
  11.                 'permission_callback' => array( $this, 'update_item_permissions_check' ), 
  12.                 'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), 
  13.             ), 
  14.             array( 
  15.                 'methods'             => WP_REST_Server::DELETABLE, 
  16.                 'callback'            => array( $this, 'delete_item' ), 
  17.                 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 
  18.                 'args'                => array( 
  19.                     'force' => array( 
  20.                         'type'        => 'boolean', 
  21.                         'default'     => false, 
  22.                         'description' => __( 'Whether to bypass trash and force deletion.' ), 
  23.                     ), 
  24.                 ), 
  25.             ), 
  26.             'schema' => array( $this, 'get_public_item_schema' ), 
  27.         ) ); 

可以看到在register_rest_route中对路由进行了正则限制:

也就是防止攻击者恶意构造ID值,但是我们可以发现$_GET和$_POST值优先于路由正则表达式生成的值:

这边没有找到ID为123hh的项目,所以返回rest_invalid。

现在我们可以忽略路由正则的限制,来传入我们自定义的ID。

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


  1. public function update_item_permissions_check( $request ) { 
  2.         $post = get_post( $request['id'] ); 
  3.         $post_type = get_post_type_object( $this->post_type ); 
  4.         if ( $post && ! $this->check_update_permission( $post ) ) { 
  5.             return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit this post.' ), array( 'status' => rest_authorization_required_code() ) ); 
  6.         } 
  7.         if ( ! empty( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( $post_type->cap->edit_others_posts ) ) { 
  8.             return new WP_Error( 'rest_cannot_edit_others', __( 'Sorry, you are not allowed to update posts as this user.' ), array( 'status' => rest_authorization_required_code() ) ); 
  9.         } 
  10.         if ( ! empty( $request['sticky'] ) && ! current_user_can( $post_type->cap->edit_others_posts ) ) { 
  11.             return new WP_Error( 'rest_cannot_assign_sticky', __( 'Sorry, you are not allowed to make posts sticky.' ), array( 'status' => rest_authorization_required_code() ) ); 
  12.         } 
  13.         if ( ! $this->check_assign_terms_permission( $request ) ) { 
  14.             return new WP_Error( 'rest_cannot_assign_term', __( 'Sorry, you are not allowed to assign the provided terms.' ), array( 'status' => rest_authorization_required_code() ) ); 
  15.         } 
  16.         return true; 
  17.     } 

可以看到,此函数通过检查文章是否实际存在,以及我们的用户是否有权限编辑这边文章来验证请求。但是当我们发送一个没有响应文章的ID时,就可以通过权限检查,并允许继续执行对update_item方法的请求。

具体到代码,就是让$post为空,就可以通过权限检查,接下来跟进get_post方法中看一下:


  1. function get_post( $post = null, $output = OBJECT, $filter = 'raw' ) {   
  2.     if ( empty( $post ) && isset( $GLOBALS['post'] ) ) 
  3.         $post = $GLOBALS['post']; 
  4.     if ( $post instanceof WP_Post ) { 
  5.         $_post = $post; 
  6.     } elseif ( is_object( $post ) ) { 
  7.         if ( empty( $post->filter ) ) { 
  8.             $_post = sanitize_post( $post, 'raw' ); 
  9.             $_post = new WP_Post( $_post ); 
  10.         } elseif ( 'raw' == $post->filter ) { 
  11.             $_post = new WP_Post( $post ); 
  12.         } else { 
  13.             $_post = WP_Post::get_instance( $post->ID ); 
  14.         } 
  15.     } else { 
  16.         $_post = WP_Post::get_instance( $post ); 
  17.     } 
  18.     if ( ! $_post ) 
  19.         return null; 

从代码中可以看出,它是用wp_posts中的get_instance静态方法来获取文章的,跟进wp_posts类,位于/wp-includes/class-wp-post.php中:


  1. public static function get_instance( $post_id ) {   
  2.         global $wpdb; 
  3.         if ( ! is_numeric( $post_id ) || $post_id != floor( $post_id ) || ! $post_id ) { 
  4.             return false; 
  5.         } 

可以看到,当我们传入的ID不是全由数字字符组成的时候,就会返回false,也就是返回一个不存在的文章。从而get_post方法返回null,从而绕过update_item_permissions_check的权限检测。

回头再看一下可执行方法upload_item:


  1. public function update_item( $request ) {   
  2.         $id   = (int) $request['id']; 
  3.         $post = get_post( $id ); 
  4.         if ( empty( $id ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) { 
  5.             return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) ); 
  6.         } 
  7.         $post = $this->prepare_item_for_database( $request ); 
  8.         if ( is_wp_error( $post ) ) { 
  9.             return $post; 
  10.         } 
  11.         // convert the post object to an array, otherwise wp_update_post will expect non-escaped input. 
  12.         $post_id = wp_update_post( wp_slash( (array) $post ), true ); 

在这边将ID参数装换为一个整数,然后传递给get_post。而PHP类型转换的时候回出现这样的情况:

所以,也就是说,当攻击者发起/wp-json/wp/v2/posts/1?id=1hhh请求时,便是发起了对ID为1的文章的请求。下面为利用[exploit-db][2]上的POC来进行测试:

新建文章:

测试:

测试结果:

多想了一下

乍一看,感觉这个洞并没有什么太大的影响,但是仔细想了一下,危害还是很大的。先不说WordPress页面执行php代码的各种插件,还有相当一部分的WordPress文章可以调用短代码的方式来输出特定的内容,以及向日志中添加内容,这是一个思路。

另一个思路就是可以进行对原来文章中的指定超链接进行修改,从而进行钓鱼。

还有一个思路,就是利用WordPress文章中解析html以及JavaScript文件包含的做法,辅助其他方法,进行攻击。

0x03 diff比较

对于该漏洞,关键的修改在/wp-includes/class-wp-post.php中:

更改了对于$post_id的参数的传入顺序和判断条件,防止了我们传入数字+字母这样的格式进行绕过。

0x04 修补方案

将WordPress更新到最新版本。

作者:佚名
来源:51CTO

时间: 2024-10-25 06:37:22

Wordpress内容注入漏洞致超67000个网站遭黑产利用的相关文章

已修复漏洞仍导致6万网站被黑;美女黑客被无故扣污名 | 宅客周刊

      有些漏洞,明明已经修复了,却依然造成不小影响:有的漏洞,明明能造成不小影响,有人却迟迟不去修复. Wordpress内容注入漏洞致超67000个网站遭黑产利用 前不久,雷锋网报道过博客管理系统 WordPress 在4.7.1 版本存在一个严重漏洞,导致攻击者可以在没有密码登录的情况下强行修改网站的文章内容.在该篇报道之前,WordPress 团队已经发布了4.7.2版本,修复了该漏洞.雷锋网当时也提醒:有相当一部分网站没有开启自动更新,考虑到 WordPress 的使用者甚多,受影

全球首例!黑产利用SS7漏洞接管用户手机卡偷钱

本文讲的是全球首例!黑产利用SS7漏洞接管用户手机卡偷钱, 据The Register援引Süddeutsche Zeitung消息,近日德国出现一起利用SS7协议漏洞盗取银行账号案例. 安全专家多年来一直警告,移动运营商间的通讯协议SS7存在严重漏洞,可能会被坏人滥用,例如将某人的电话和短信重定向到攻击者的设备.现在,第一起滥用漏洞造成资金损失的案例出现了. 西班牙电信运营商O2的德国分部向媒体确认,有攻击者利用SS7漏洞拦截用户手机接收的短信来突破他们银行账号的二次验证保护机制,并将钱洗劫一

新曝WordPress REST API内容注入漏洞详解

近日,来自Sucuri的研究人员发现WordPress存在重大漏洞,漏洞在于WordpressREST API,成功利用该漏洞可删除页面或修改页面内容.官方很快发布了升级版Wordpress,但很多管理员没有及时升级,以至于被篡改的网页从最初的几千一路飙升到了150万,在此也提醒各位管理员尽快升级. 一.漏洞详情 1. 漏洞信息: WordPress是一个以PHP和MySQL为平台的自由开源的博客软件和内容管理系统.在4.7.0版本后,REST API插件的功能被集成到WordPress中,由此

ECShop曝高危SQL注入漏洞 360首推临时解决方案

日前,第三方漏洞报告平台乌云曝出国内知名网店系统ECShopGBK版本存在高危SQL注入漏洞,(http://wooyun.org/bugs/wooyun-2010-09463),黑客利用此漏洞可获得管理员账号密码,窃取网站数据.360网站安全检测平台对注册网站检测发现,国内3000余个网站存在此漏洞,是近期流行度最高的漏洞之一.目前,360已独家提供了应对该漏洞的临时解决方案. 360网站安全检测平台网址:http://webscan.360.cn ECShop是一款基于PHP与MYSQL开发

ShopEx曝SQL注入漏洞电商网站面临“拖库”威胁

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 近日,乌云漏洞平台爆料称ShopEx4.8.5版存在SQL注入漏洞(http://www.wooyun.org/bugs/wooyun- 2010-08597),黑客利用该漏洞可获得网站管理员密码,进而控制网站服务器,窃取用户帐号密码(又称为"拖库").360网站安全检测平台发现,目前绝大多数ShopEx网站用户均存在该漏

WordPress REST API 内容注入/权限提升漏洞

WordPress 是一个以 PHP 和 MySQL 为平台的自由开源的博客软件和内容管理系统,至少有 1800 万个网站使用该系统.在 4.7.0 版本后,REST API 插件的功能被集成到 WordPress 中,由此也引发了一些安全性问题. WordPress REST API 内容注入/权限提升漏洞于 1 月 22 日被安全公司 Sucuri 研究员 Marc-Alexandre Montpas 发现并告知 WordPress .经过 WordPress 紧急修复,于 1 月 26 日

WordPress统计分析插件WP Statistics出现SQL注入漏洞 攻击者可窃取用户数据

安全研究员在WP Statistics插件中发现了一个缺陷,可使黑客貌似合理地窃取数据库,甚至远程劫持网站.该插件是一个非常流行的WordPress插件,用于超过30万个网站上.利用WP Statistics插件,网站管理员可查明网站信息,包含实时在线用户数量,网页统计和访客数量. WP Statistics插件SQL注入漏洞 Sucuri公司的安全研究员发现WP Statistics插件中可能存在一个SQL注入漏洞,可使远程攻击者利用订阅账户从网站数据库中窃取数据. 让我们先看一下SQL注入背

PHP代码网站防范SQL注入漏洞攻击的建议

所有的网站管理员都会关心网站的安全问题.说到安全就不得不说到SQL注入攻击(SQL Injection).黑客通过SQL注入攻击可以拿到网站数据库的访问权限,之后他们就可以拿到网站数据库中所有的数据,恶意的黑客可以通过SQL注入 功能篡改数据库中的数据甚至会把数据库中的数据毁坏掉.做为网络开发者的你对这种黑客行为恨之入骨,当然也有必要了解一下SQL注入这种功能方式的原理并 学会如何通过代码来保护自己的网站数据库.今天就通过PHP和MySQL数据库为例,分享一下我所了解的SQL注入攻击和一些简单的

PHP代码网站如何防范SQL注入漏洞攻击建议分享_php技巧

黑客通过SQL注入攻击可以拿到网站数据库的访问权限,之后他们就可以拿到网站数据库中所有的数据,恶意的黑客可以通过SQL注入功能篡改数据库中的数据甚至会把数据库中的数据毁坏掉.做为网络开发者的你对这种黑客行为恨之入骨,当然也有必要了解一下SQL注入这种功能方式的原理并学会如何通过代码来保护自己的网站数据库.今天就通过PHP和MySQL数据库为例,分享一下我所了解的SQL注入攻击和一些简单的防范措施和一些如何避免SQL注入攻击的建议. 什么是SQL注入(SQL Injection)? 简单来说,SQ